locked
Get item from Json RRS feed

  • Question

  • I'm able to get an element from some Json like this:

    //response.Content came from a HTTP request

    var values = System.Text.Json.JsonSerializer.Deserialize<Dictionary<string, object>>(response.Content);


    and values["results"] is this:

    "[{\"v_type\":\"PhoneCall\",\"attributes\":{\"eventDate\":{\"MAX\":0,\"MIN\":0,\"AVG\":0},\"callLength\":{\"MAX\":0,\"MIN\":0,\"AVG\":0}}}]"

    I need to get a dictionary object for the element "attributes" from the Json above.  How can I do this?  Since that's a Json element I tried this again:

    var newvalues2 = System.Text.Json.JsonSerializer.Deserialize<Dictionary<string, object>>(values["results"].ToString());



    but I get an error message:

    "The JSON value could not be converted to System.Collections.Generic.Dictionary`2[System.String,System.Object]"


    How can I get a Dictionary object for the data under "attributes"?

    Thank you

    Thursday, June 4, 2020 11:01 PM

All replies

  • I found a solution which Newtonsoft.Json, but, if anyone knows a solution using only System.Text.Json - please let me know.  I'm trying to get away from Newtonsoft.Json.

    //response.Content is from an HTTP response
    dynamic responseContent = JsonConvert.DeserializeObject(response.Content)
    JObject rss = responseContent.results[0]
    var newDict = rss["attributes"].ToObject<Dictionary<string, object>>();


    Thursday, June 4, 2020 11:47 PM
  • Hi moondaddy,

    Thank you for posting here.

    Personally, I think it would be better to use the features in Visual Studio to create a new class and then deserialize the json into a list.

    Copy the json object, then click on the options in the picture.

    After that, you can easily deserialize Json into a list.

        List<Rootobject> responseContent = JsonSerializer.Deserialize<List<Rootobject>>(File.ReadAllText(@"d:\test\json\1.json"));
    

    If you really need to convert the attribute into a Dictionary, you can also do this:

     JsonElement jsonElement = JsonSerializer.Deserialize<JsonElement>(File.ReadAllText(@"d:\test\json\1.json"));
     var attributes =jsonElement[0].GetProperty("attributes").ToString();
     Dictionary<string, object> result = JsonSerializer.Deserialize<Dictionary<string, object>>(attributes);

    Hope this could be helpful.

    Best Regards,

    Timon


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.


    Friday, June 5, 2020 2:29 AM
  • Hi,

    Has your issue been resolved?

    If so, please click "Mark as Answer" for the answer that solved your problem, so that it will help other members to find the solution quickly if they face a similar issue.

    Best Regards,

    Timon


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Tuesday, June 9, 2020 8:57 AM
  • I 100% agree with Timon that you should always use strongly typed classes to convert from JSON if you know the structure of the data. There is 0 reason to do otherwise. The only time you should be working with the raw JSON yourself is if you are dealing with unknown JSON but that would be exceedingly rare. Is there a reason you cannot use a strongly typed object.

    As for reading the attributes you have to understand that if you aren't using a strongly typed object then all the JSON data is going to get treated as JsonElement instead. Note that this is true even for JSON.NET, it just calls them JToken. If you know that there is an attributes property in the JSON and you know that it is also a dictionary then a strongly typed object is clearly the way to go. But if you truly want to treat it as a dictionary then you have to convert from the JsonElement to a dictionary. To retrieve the child values in the element you use EnumerateObject. What you get back is an enumerator that walks through the child values. However because JsonSerializer tries to figure out the types for you (and you may have custom type converters registered) you'll get back object in all cases and you have to decide what to do from there. It might be an int or a string or another JsonElement (because they can be nested) so you'll have to potentially parse hierarchies of data. That is why strong types work so much better.

    As a final aside note that if the child is actually an array then you cannot use EnumerateObject, use EnumerateArray instead. You'll have to look at the ValueKind property to determine if it is an array or not. In general you'll want a simple converter method to convert from ValueKind to the object you care about.

    //Just an example, not tested
    public object ToValue ( JsonElement element )
    {
       switch (element.ValueKind)
       {
          //Primitives
          case JsonValueKind.False: return false;
          case JsonValueKind.True: return true;
          case JsonValueKind.String: return element.GetString();
    
          case JsonValueKind.Null:
          case JsonValueKind.Undefined: return null;
    
          //Could be double, int, long, etc
          case JsonValueKind.Number: return element.GetDouble();
    
          //Objects
          case JsonValueKind.Object: //Parse the child object
         
          case JsonValueKind.Array: //Parse the array      
       };
    
       //Have no idea
       return null;
    }


    Michael Taylor http://www.michaeltaylorp3.net

    Tuesday, June 9, 2020 1:39 PM