Beerion
Beerion

Reputation: 51

C# Iterate over a JSON object

I'm trying to use the .Net Json deserializer System.Text.Json to iterate over the following Json input.

I've found methods for iterating by "person_id" if it were the top level in the json structure (see below), but I haven't been able to track down a method for looping through all of the next level items.

I think the NewtonSoft JArray and JObject are pretty close to what I need (I may pursue that) but wasn't sure if Microsofts solution had a way to do it...

Is this possible with Microsoft's System.Text.Json library?

{
  "0": {
    "person_id": "0",
    "last_name": "Greg",
    "first_name": "Craig",
  },
  "1": {
    "person_id": "1",
    "last_name": "Doe",
    "first_name": "John",
  }
}

JsonElement solution for extracting an object by property name (ie I can get John Doe's information this way).

using (JsonDocument document = JsonDocument.Parse(jsonString))
{
    JsonElement root = document.RootElement;

    JsonElement studentsElement = root.GetProperty("1");
}

Upvotes: 5

Views: 20074

Answers (2)

Faisal AL Mahmud
Faisal AL Mahmud

Reputation: 550

You can use JsonElement.EnumerateObject. It is used to enumerate the properties in the JSON object represented by this JsonElement

var options = new JsonDocumentOptions 
{
   AllowTrailingCommas = true,
   CommentHandling = JsonCommentHandling.Skip
};
using (JsonDocument document = JsonDocument.Parse(jsos, options))
{
    foreach (JsonProperty property in document.RootElement.EnumerateObject())
    {
        string key = property.Name;
        JsonElement valueElement = property.Value;
        string person_id = valueElement.GetProperty("person_id").GetString();
        string last_name = valueElement.GetProperty("last_name").GetString();
        string first_name = valueElement.GetProperty("first_name").GetString();
     }
 }

Upvotes: 8

Geoff James
Geoff James

Reputation: 3180

Looks similar to some JSON I've had to tackle before. It helps to remember that JSON objects are just key/value pairs.

With this in mind, the data structure you have could be interpreted as a Dictionary in C#.

I've used Newtonsoft.Json in my examples, but they are easy to swap over to use System.Text.Json.

In its simplest form, you could use:

var dictionary = JsonConvert.DeserializeObject<Dictionary<string, object>>(jsonString);

Which will give you a Dictionary where the key is the "0", "1" properties, and the value is the object representing the person info inside.

You can then run a simple foreach loop over the Dictionary, or its keys, or values, like so:

foreach (var item in dictionary)
{
    var key = item.Key;
    var person = item.Value;
}

But the person (item.Value) is still only of type object.

This is where you can create a class to represent each Person's info, decorating the properties to match what's in the JSON data structure, like so:

public class Person 
{
    [JsonProperty("person_id")]
    public string PersonId { get; set; }
    
    [JsonProperty("first_name")]
    public string FirstName { get; set; }
    
    [JsonProperty("last_name")]
    public string LastName { get; set; }
}

and instead deserialize your JSON to a Dictionary<string, Person>:

var dictionary = JsonConvert.DeserializeObject<Dictionary<string, Person>>(jsonString);

Which means each value of the entry in the dictionary is an instance of Person, and you can access the strongly-typed properties of each, like so:

foreach (var item in dictionary)
{
    var key = item.Key; // although you probably won't need this
    Console.WriteLine(key);

    var person = item.Value;
    Console.WriteLine(person.PersonId);
    Console.WriteLine(person.FirstName);
    Console.WriteLine(person.LastName);
}

// which gives the following output:
> 0
> 0
> Craig
> Greg
> 1
> 1
> John
> Doe


Although I've used Newtonsoft.Json above, it's easy to "migrate" the above sample to use System.Text.Json.

  • Instead of JsonConvert.DeserializeObject<T>, use JsonSerializer.Deserialize<T>; and
  • Instead of using [JsonProperty("property_name")] attribute, you can use [JsonPropertyName("property_name")].

Hope this helps.

Upvotes: 3

Related Questions