Davide Di Giovanni
Davide Di Giovanni

Reputation: 41

Deserialize a generic JSON and use its properties

I need to call an API that returns a JSON that can vary. Sometimes the response could be something like:

[
  {
    "name": "value"
  }
]

while other times

[
  {
    "property": "value"
  }
]

or even

[
  {
    "name": "value",
    "status": "value",
    "count": "value"
  }
]

Basically, I need to retrieve all values in this JSON for later use.

I tried var prova = JsonConvert.DeserializeObject<dynamic>(result);, but I can't access the properties using ["indexName"] because the index can vary depending on some factors. Any ideas?

Upvotes: 3

Views: 1811

Answers (2)

EdSF
EdSF

Reputation: 12341

Assumption:

You're getting an array of objects from the api (that doesn't return null data - re: probably why the structure is "dynamic").

Here's one way:

//System.Text.Json
var foo = JsonSerializer.Deserialize<JsonElement>(array_from_api);

//It's an array (assumption) of one or more objects
foreach (JsonElement element in foo.EnumerateArray())
{
    //iterate through each object's properties
    foreach (JsonProperty o in element.EnumerateObject())
    {
        //Assumption: value isn't a nested object/array, otherwise adjust...
        Console.WriteLine($"{o.Name} = {o.Value}");
    }
}

//Json.Net

//It's an array (assumption) of one or more objects
JArray deserialized = JsonConvert.DeserializeObject<JArray>(array_from_api);

foreach (JObject jo in deserialized)
{
    //iterate through each JObject's properties
    foreach (JProperty p in jo.Properties())
    {
        Console.WriteLine($"{p.Name} = {p.Value}");

    }

}

Note: If the structure is more complex - more nesting, you'll have to do some checks and adjust accordingly (re: nested arrays, objects, etc)

Upvotes: 1

Abdelkrim
Abdelkrim

Reputation: 1221

You can create a POCO that that has all the possible properties if they are finite. Like the following :

public class Result { 
   public string name { get; set; } 
   public string property { get; set; } 
   public string status { get; set; } 
   public string count{ get; set; } 
} 

And then you can use: var prova = JsonConvert.DeserializeObject<IEnumerable<Result>>(Result);. I change the deserialization to using an IEnumerable because I see that your JSON is an array.

And then you can check if the values are null before accessing them. Since every Result object will only have the property that was available in JSON as non-null.

Alternatively, you can use a Dictionary<string, string> or Dictionary<string, int> and do the following :

var prova = JsonSerializer.Deserialize<IEnumerable<Dictionary<string, string>>>(result) as List<Dictionary<string, string>>;

and then you can access every object of the list and access the property you want like this or TryGetValue Method for more safety.

       Console.WriteLine(prova[0]["name"]);  

Upvotes: 2

Related Questions