如何在 C 中将 JSON 元素名称和值推送到字典中#

How to push JSON element names and values into a dictionary in C#

提问人:Douar Gwenn 提问时间:10/6/2023 最后编辑:Douar Gwenn 更新时间:10/11/2023 访问量:83

问:

我正在处理一个具有先验部分未知结构的对象。我不确定我是否可以使用反序列化对象方法,因为我无法预测我希望定位的确切结构长度和命名。Json

我只知道结构骨架(看着预览器)会是这样的:Json

[JSON]
    [meta] 
        metaname1: metavalue1
        ...
        metanameN: metavalueN
    [target]
        [0]
            targetname1: targetvalue1
            ...
            targetnameP: targetvalueP

实际提取的结构如下:

{[meta, {
  "limit": 100,
  "offset": 0,
  "count": 1,
  "total": 1
}]}
{[target, [
  {
    "open": 173.99,
    "high": 175.46,
    "low": 172.675,
    "last": 175.38,
    "close": 173.66,
    "volume": 607334.0,
    "date": "2023-10-05T21:00:00+02:00",
    "symbol": "AAPL",
    "exchange": "IEXG"
  }
]]}

我想跳过“元”节点,专注于“目标”节点,并将一系列键和值(targetname1、targetvalue1),...,(targetnameP、targetvalueP)推送到字典中。在给定的“地址”从互联网读取数据后,我使用库加载了对象。JsonNewtonsoft.Json

using (HttpClient client = new HttpClient())
{
    Task<HttpResponseMessage> response = client.GetAsync(address);
    using (HttpResponseMessage message = response.Result)
    {
        using (HttpContent content = message.Content)
        {
            string jsonData = content.ReadAsStringAsync().Result;
            JObject jsonObj = JObject.Parse(jsonData);
        }
    }
}

我不确定下一步该如何进行。


补遗


现在我正在尝试这个,但我仍然被卡住了。

class Program
{
    static void Main(string[] args)
    {
        string jsonData = @"
            {[meta, {
               "limit": 100,
               "offset": 0,
               "count": 1,
               "total": 1
            }]}
            {[target, [
              {
                "open": 173.99,
                "high": 175.46,
                "low": 172.675,
                "last": 175.38,
                "close": 173.66,
                "volume": 607334.0,
                "date": "2023-10-05T21:00:00+02:00",
                "symbol": "AAPL",
                "exchange": "IEXG"
              }
            ]]}";

        Dictionary<string, object> jsonDict = JsonConvert.DeserializeObject<Dictionary<string, object>>(jsonData);
        object jsonSubData = jsonDict["target"];
    }
}

我无法将“jsonSubData”放入另一个字典。


这是一个有效的解决方案吗?


我想出了这个。它似乎有效。我不确定这是最有效的解决方案。

class Program
{
    static void Main(string[] args)
    {
        string jsonData = @"Same structure as before";

        JObject jsonObj = JObject.Parse(jsonData);
        JObject jsonSubObj = jsonObj["data"].Values<JObject>().First();

        Dictionary<string, string> jsonDict = new Dictionary<string, string>();
        foreach (JProperty property in jsonSubObj.Properties())
            jsonDict.Add(property.Name, property.Value.ToString());
    }
}
C# JSON json.net

评论

1赞 Bagus Tesa 10/6/2023
发布实际的 JSON 供人们使用会容易得多,而不是 JSON 预览器 thingy。
0赞 jason.kaisersmith 10/6/2023
你需要一个JObject有什么具体的原因吗?为什么不能反序列化为一个简单的类?
0赞 iSR5 10/6/2023
最简单的方法是将 JSON 反序列化为 ,然后您可以从那里开始工作。Dictionary<string, object>
0赞 Douar Gwenn 10/6/2023
@jason.凯撒史密斯。也不确定。我只是在调查可以从课堂上得到什么。JObject
1赞 Douar Gwenn 10/6/2023
@iSR5。我正在挣扎,因为我正在这样做,这返回了一个异常。按照你所说的去做,确实返回了我所追求的两级('meta'、'target')节点结构。然后,我可以依次访问“目标”部分,我想,我需要再次反序列化到另一个字典中。谢谢。JsonConvert.DeserializeObject<Dictionary<string, string>>(jsonData);JsonConvert.DeserializeObject<Dictionary<string, object>>(jsonData);

答:

1赞 iSR5 10/6/2023 #1

我假设 json 根将始终包含 和 属性。如果是这样,您可以这样做:metatarget

public sealed class DataContainer
{
    [JsonProperty("meta")]
    public Dictionary<string, object>? Meta { get; set; }

    [JsonProperty("target")]
    public Dictionary<string, object>[]? Data { get; set; }
}

然后,你只需这样做:

string json = @"{""meta"":{""limit"":100,""offset"":0,""count"":1,""total"":1},""target"":[{""open"":173.99,""high"":175.46,""low"":172.675,""last"":175.38,""close"":173.66,""volume"":607334.0,""date"":""2023-10-05T21:00:00+02:00"",""symbol"":""AAPL"",""exchange"":""IEXG""}]}";

DataContainer? data = JsonConvert.DeserializeObject<DataContainer>(json);

现在,您可以访问该属性,并循环访问其所有元素(对象)。Data

如果您使用的是 ,则只需更改以下内容:System.Text.Json

JsonPropertyAttribute         -> JsonPropertyNameAttribute 
JsonConvert.DeserializeObject -> JsonSerializer.Deserialize

如果你的 JSON 根目录的键比上面的例子多,并且你只需要 ,那么你可以省略该属性,然后使用 并将 设置为 ,这将确保你只反序列化你在类中提供的任何内容。targetMetaJsonSerializerSettingsMissingMemberHandlingMissingMemberHandling.IgnoreDataContainer

评论

0赞 Douar Gwenn 10/10/2023
非常感谢@iSR5。你的回答非常简洁、聪明和有帮助。