Home > Net >  C# - Having trouble iterating over a dynamic JSON
C# - Having trouble iterating over a dynamic JSON

Time:11-06

I am trying to pull JSON data from a website and I am having some trouble iterating over the objects it returns. Can someone please assist with navigating this structure? I am confused by it not being uniform.

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);
    }
}

The JSON array I'm dealing with is below. My goal is to iterate through item and get all of the date1 and date2 values. I don't need anything else.

{
    "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
    }
}

CodePudding user response:

You are making extra work for yourself by using dynamic as you lose IntelliSense as well as compile-time type checking. The underlying type returned by Json.NET for dynamic will typically be some subtype of JToken, so the easiest way to accomplish your task is to deserialize to JToken and use SelectTokens() like so:

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}.");
}

Which prints

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

Notes:

Demo fiddle here

  • Related