Brettvd
Brettvd

Reputation: 13

deserialize json with children items

Having to deserialize JSON from an API call. Posting the JSON steam below. Have to get each "area" node. Notice that some have children of children in it (this were I'm having trouble). Didn't even know what JSON was before this time yesterday (said I've been out a while).

What I've figured out: Have Netwonsoft.Json reference added Converted it to XML to see if that helped but thinking staying JSON will have better performance.

vb.net class has the following properties: Area_Name as string ("ID" in JSON) Area_ID as string ("Name" in JSON) Parent_ID as string (Parent "ID" in JSON)

So, need idea where to start to pull all nodes out of the following JSON. -----JSON Stream-----

{"areas":
    [{"id":"1353331688024941487","name":"NGT","children":
        [{"id":"1353331688024941488","name":"Other","children":
            [
             {"id":"1353331688024941489","name":"Independence Office","children":[]},
             {"id":"1353331688024941490","name":"Lordstown Pipe Receipt Site (PRS)","children":[]},
             {"id":"1353331688024941491","name":"Marion Pipe Receipt Site (PRS)","children":[]},
             {"id":"1353331688024941492","name":"Marion Warehouse Facility","children":[]},
             {"id":"1353331688024941493","name":"Port of Toledo Pipe Receipt Site (PRS)","children":[]},
             {"id":"1353331688024941494","name":"Spread -1 - No facility","children":[]},
             {"id":"1353331688024941495","name":"Spread -2 - Wadsworth Office","children":[]},
             {"id":"1353331688024941496","name":"Spread -3 - Toledo Office","children":[]},
             {"id":"1353331688024941497","name":"Spread -4 - Dundee Office","children":[]}
            ]
         },
         {"id":"1353331688024941498","name":"Spread-1","children":
            [
            {"id":"1353331688024941499","name":"Compressor Station 1","children":[]},
            {"id":"1353331688024941500","name":"Field Inspectors 1","children":[]},
            {"id":"1353331688024941501","name":"Meter Station 1","children":[]},
            {"id":"1353331688024941502","name":"Meter Station 2","children":[]},
            {"id":"1353331688024941503","name":"Meter Station 3","children":[]},
            {"id":"1353331688024941504","name":"NDE Testing 1","children":[]},
            {"id":"1353331688024941505","name":"Pipeline 1","children":[]},
            {"id":"1353331688024941506","name":"Wareyard 1-1","children":[]}
            ]
         },
        {"id":"1353331688024941507","name":"Spread-2","children":
            [
             {"id":"1353331688024941508","name":"Compressor Station 2","children":[]},
             {"id":"1353331688024941509","name":"Field Inspectors 2","children":[]},
             {"id":"1353331688024941510","name":"Meter Station 5","children":[]},
             {"id":"1353331688024941511","name":"NDE Testing 2","children":[]},
             {"id":"1353331688024941512","name":"Pipeline 2","children":[]},
             {"id":"1353331688024941513","name":"Wareyard 2-1","children":[]}
            ]
        },
        {"id":"1353331688024941514","name":"Spread-3","children":
            [
             {"id":"1353331688024941515","name":"Compressor Station 3","children":[]},
             {"id":"1353331688024941516","name":"Compressor Station 4","children":[]},
             {"id":"1353331688024941517","name":"Field Inspectors 3","children":[]},
             {"id":"1353331688024941518","name":"Meter Station 6","children":[]},
             {"id":"1353331688024941519","name":"NDE Testing 3","children":[]},
             {"id":"1353331688024941520","name":"Pipeline 2","children":[]},
             {"id":"1353331688024941521","name":"Wareyard 3-1","children":[]}
            ]
        },
        {"id":"1353331688024941522","name":"Spread-4","children":
            [
             {"id":"1353331688024941523","name":"Field Inspectors 4","children":[]},
             {"id":"1353331688024941524","name":"Meter Station 4","children":[]},
             {"id":"1353331688024941525","name":"NDE Testing 4","children":[]},
             {"id":"1353331688024941526","name":"Pipeline 4","children":[]},
             {"id":"1353331688024941527","name":"Wareyard 4-1","children":[]},
             {"id":"1353331688024941528","name":"Wareyard 4-3","children":[]},
             {"id":"1353331688024941529","name":"Wareyard 4-4","children":[]}

            ]
        }
    ]
    }
    ]
}

Thanks, appreciate the help.

Upvotes: 0

Views: 1214

Answers (2)

Visual Studio will create the classes you need or you can use the online robots. In VS, with the JSON on the clipboard, Edit -> Paste Special -> Paste JSON as classes

Both are a little dense in that they will not recognize that the Child classes are in fact the same and you can use the same one for both. In fact, the Area and Child classes are also identical:

Public Class AreaContainer
    Public Property areas As AreaItem()
End Class

Public Class AreaItem
    Public Property id As String
    Public Property name As String
    Public Property children As AreaItem()    ' no need for a Child1
End Class

Deserialize:

Dim jstr = ...wherever you get it
Dim myareas = JsonConvert.DeserializeObject(Of AreaContainer)(jstr)

I am not sure what you are after, but this will print the names of the NGT.Other children and the count of their children.

For n As Int32 = 0 To myareas.areas(0).children(0).children.Count - 1
    Console.WriteLine("Name {0}    => children: {1}",
                        myareas.areas(0).children(0).children(n).name,
                        myareas.areas(0).children(0).children(n).children.Count)
Next

Name Independence Office => children: 0
Name Lordstown Pipe Receipt Site (PRS) => children: 0
Name Marion Pipe Receipt Site (PRS) => children: 0
Name Marion Warehouse Facility => children: 0
Name Port of Toledo Pipe Receipt Site (PRS) => children: 0
Name Spread -1 - No facility => children: 0
Name Spread -2 - Wadsworth Office => children: 0
Name Spread -3 - Toledo Office => children: 0
Name Spread -4 - Dundee Office => children: 0

  • Intellisense will help you navigate the structure once you have the classes
  • The Locals Window will also expand the collection and help "see" how to get to different data elements

As shown in other posts here, you can simplify the resulting object your code has to work with by first parsing the JSON, the deserialize just the areas portion to an array. It elides the myAreas variable as well as the AreaContainer class, both of which serve little purpose.

Upvotes: 1

Chetan
Chetan

Reputation: 6901

You need to have one more class "AreaModel" with one property "Areas" in it. So your classes should looks as following.

public class AreaModel
{
    public List<Area> Areas { get; set; }
}
public class Area
{
    [JsonProperty(PropertyName = "id")]
    public string Area_Name 
    {
        get;
        set;
    }

    [JsonProperty(PropertyName = "name")]
    public string Area_ID {get;set;}

    [JsonProperty(PropertyName= "children")]
    public List<Area> Children 
    { 
        get;set;
    }
}

Then you can deserialize the JSON string as following.

var areaModel = JsonConvert.DeserializeObject<AreaModel>(areaJSON);

foreach (var area in areaModel.Areas)
{
    DisplayAreas(area);
}

private static void DisplayAreas(Area area)
{
    Console.WriteLine(area.Area_Name);
    if(area.Children != null && area.Children.Count > 0)
    {
        foreach(var child in area.Children)
        {
            DisplayAreas(child);
        }
    }
}

Upvotes: 0

Related Questions