How to cycle for dynamic JObjects in another JObject?

Viewed 99

Actually i'm am processing some JSON data get from some API in an old VB.NET project in Framework 3.5

I'm stuck in the processing of the following response:

{
  "data": {
    "89359": {
      "name": "A",
      //...
    },
    "89360": {
      "name": "B",
      //...
    }
  }
}

Each item in data is dynamic but the API doesn't set the data as an array, i was trying to get the data from each item as i was yet doing for JSON arrays like this:

Dim options As JObject = JObject.Parse(json)
For Each opt As JObject In options("data")
    MsgBox(opt("name"))
Next

But it's not working in this case as as i said data is not an array...

So how could process data from that JSON as 89359 and 89360 are dynamic?

2 Answers

Your problem is that options("data") is declared to be of type JToken while actually being of type JObject, so when you enumerate it you are actually enumerating its JProperty children. But what you need are the values of those JProperty objects which are one level deeper in the hierarchy:

For Each jProperty As JProperty In options("data")
    Dim propertyName = jProperty.Name ' The "89359" names, in case you need them for some reason
    Dim opt As JObject = jProperty.Value
    Dim name As String = opt("name")  ' Cast the name to a String using the JToken implicit casting operator
    ' Use the name as required
    MsgBox(name)
Next    

Demo fiddle here.

Assuming that the object that has the name property has other properties, what I would do is:

  1. Create a class to represent the object with the name property
  2. Deserialize the incoming data into a JObject
  3. Get the "data" item of the JObject
  4. Call ToObject from step 3 to a Dictionary(Of Integer, DataObject)

Here is an example:

Imports Newtonsoft.Json
Imports Newtonsoft.Json.Linq

Module Module1

    Sub Main()
        Dim input As String = "{""data"": {""89359"": {""name"": ""A"" }, ""89360"": {""name"": ""B"" } } }"
        Dim data = JsonConvert.DeserializeObject(Of JObject)(input)
        Dim dataItems = data.Item("data").ToObject(Of Dictionary(Of Integer, DataObject))

        For Each dataItem In dataItems
            Console.WriteLine("Key: {0}, DataObject.Name: {1}", dataItem.Key, dataItem.Value.name)
        Next
        Console.ReadLine()
    End Sub

End Module

Public Class DataObject

    Public Property name As String

    ' ...

End Class

Now the objects exist as an array via the dataItems.Values method.

Live Example: Fiddle

Related