3

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?

Uwe Keim
  • 39,551
  • 56
  • 175
  • 291
  • 1
    You could [deserialize your JSON into a dictionary](https://www.newtonsoft.com/json/help/html/DeserializeDictionary.htm) and then either loop through all the key-value-pairs or use `TryGetValue` to check if the ones you are interested in are present. – Heinzi Oct 18 '21 at 15:45
  • As mentioned in the above comments, you can work like this `public void Save(dynamic content){ var events = content.ToString(); Dictionary> eventls = JsonConvert.DeserializeObject>(events); }` – Mounica Oct 18 '21 at 18:00
  • @Heinzi / @mounica It's an `array` ... – EdSF Oct 18 '21 at 18:49
  • Reopen vote: dupe link doesn't apply to `array` – EdSF Oct 21 '21 at 16:06

2 Answers2

2

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"]);  
Abdelkrim
  • 1,083
  • 8
  • 18
1

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)

EdSF
  • 11,753
  • 6
  • 42
  • 83