C# - 在循环访问动态 JSON 时遇到问题

C# - Having trouble iterating over a dynamic JSON

提问人:eek 提问时间:11/6/2023 最后编辑:dbceek 更新时间:11/6/2023 访问量:84

问:

我正在尝试从网站中提取 JSON 数据,但在迭代它返回的对象时遇到了一些麻烦。有人可以协助浏览这个结构吗?我对它不统一感到困惑。

using (var httpClient = new HttpClient())
{
    httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", "myToken");
    httpClient.BaseAddress = new Uri("https://app.website.com/data/");

    HttpResponseMessage response = httpClient.GetAsync("getData.json?item=myItem").Result;
    response.EnsureSuccessStatusCode();

    dynamic result = JsonConvert.DeserializeObject(response.Content.ReadAsStringAsync().Result);
    Console.WriteLine("Result: " + result);

    dynamic jsonArray = result.results;
                
    foreach (var item in jsonArray.items)
    {
        Console.WriteLine(item.date1);
    }
}

我正在处理的 JSON 数组如下。我的目标是遍历并获取所有 和 值。我不需要别的。itemdate1date2

{
    "results": {
        "copyright": "Copyright",
        "items": [{
            "info": {
                "longname": "XXX",
                "shortname": "YYY"
            },
            "item": [{
                "date1": "2022-01-01",
                "date2": "2022-01-05",
            }, {
                "date1": "2022-04-01",
                "date2": "2021-04-07",
            }],
            "key": {
                "keyName": "AAA",
                "keySym": "BBB",
            },
            "symString": "BBB"
        }],
        "count": 1
    }
}
C# 数组 JSON json.net

评论

0赞 Rand Random 11/6/2023
您提供的 JSON 是动态的还是不统一的?
1赞 gunr2171 11/6/2023
您反序列化而不是构建具体模型或使用是否有原因?dynamicJToken.Parse
0赞 eek 11/6/2023
我以前从未使用过其他任何东西,所以这是唯一的原因。我认为这个 json 有些不规则,因为它有额外的项目,尽管我知道这并不一定会使它不规则。它只是比我习惯的工作更复杂。dynamickey
0赞 Rand Random 11/6/2023
也许可以考虑使用: learn.microsoft.com/en-us/visualstudio/ide/reference/... - 而不是反序列化到生成的类

答:

2赞 dbc 11/6/2023 #1

通过使用 IntelliSense 以及编译时类型检查,你正在为自己做额外的工作。Json.NET for 返回的基础类型通常是 JToken 的某个子类型,因此完成任务的最简单方法是反序列化为 SelectTokens() 并使用 SelectTokens(),如下所示:dynamicdynamicJToken

var result = JsonConvert.DeserializeObject<JToken>(jsonString);
var dates = result.SelectTokens("results.items[*].item[*]")
    .Select(i => new { date1 = i["date1"].ToObject<DateOnly>(), date2 = i["date2"].ToObject<DateOnly>() });
foreach (var item in dates)
{
    Console.WriteLine($"Date1={item.date1}, Date2={item.date2}.");
}

哪些打印

Date1=01/01/2022, Date2=01/05/2022.
Date1=04/01/2022, Date2=04/07/2021.

笔记:

在这里演示小提琴

评论

0赞 gunr2171 11/6/2023
和之间有什么区别吗?JsonConvert.DeserializeObject<JToken>(jsonString)JToken.Parse(jsonString)
1赞 dbc 11/6/2023
@gunr2171 - 很少。 自动加载行信息,而不加载行信息,导致内存使用量略有增加。使用 时传递设置也更容易。但实际上我只是使用了,因为 OP 已经在使用它了。JToken.Parse(jsonString)JsonConvert.DeserializeObject<JToken>(jsonString)DeserializeObject()DeserializeObject()
0赞 eek 11/6/2023
这效果很好!谢谢!
0赞 eek 11/6/2023
您将如何访问该物业?我试过了,但没有用keyNamekeyresults.items[*].key
1赞 dbc 11/6/2023
@eek - ,请参见 dotnetfiddle.net/RmMhpA"results.items[*].key.keyName"