Search code examples
arraysjsonvb.netjavascriptserializer

How to access data from objects nested in json array


I need to access data in nested json array of objects to be able to manipulate it further , using javascriptserializer in vb.net 4.0.

Here's the example string:

json: {"multicast_id":216,"success":3,"failure":3,"canonical_ids":1,"results":[{"message_id":"1:0408"},{"errord":"Unavailable"}]}

And here's the code I've written so far:

Class main
Public Property multicast_id As Integer
Public Property success As Integer
Public Property failure As Integer
Public Property canonical_ids As Integer
Public Property results As Results()
End Class

Class Results
Public Property message_id As String
Public Property errord As String
End Class


Public Class Form1

Private Sub btnTest_Click(sender As Object, e As EventArgs) Handles btnTest.Click
    Dim json As String
    json = txtInsert.Text

    Try
        Dim ser As JavaScriptSerializer = New JavaScriptSerializer()
        Dim exmp As main = New main
        exmp = ser.Deserialize(Of main)(json)

        Console.WriteLine(exmp.canonical_ids)
        Console.WriteLine(exmp.multicast_id)

        For Each item As Object In exmp.results
            For Each example As String In item
                Console.WriteLine("example")
            Next
        Next

    Catch ex As Exception
        MsgBox(ex.ToString)
    End Try
End Sub
End Class

I'm getting an error on the inner for each statement. If anyone could help me out with this, I'd really appreciate it.


Solution

  • You are getting the nested object correctly.

    Instead your issue that once you get that nested object you are trying to use For Each to get each string property of that result. That is invalid.

    For example, this doesn't work because Results does not implement IEnumerable so you can't use For Each on in:

    Dim r as new Results();
    r.message_id = "1:0408"
    r.errord = "Unavailable"
    For Each example As String In r ' <- this will throw an error
    Next
    

    Once you have a reference to the Results you then need to access it by property name:

    For Each item As Results In exmp.results
        Console.WriteLine("message_id: {0}", item.message_id)
        Console.WriteLine("errord: {0}", item.errord)
    Next
    

    If you need to access the properties by name, then change Results to a different type.

    For example, you can define results as an array of Dictionary(of String, Object) like this:

    Class main
        Public Property multicast_id As Integer
        Public Property success As Integer
        Public Property failure As Integer
        Public Property canonical_ids As Integer
        Public Property results As Dictionary(Of String, Object)()
    End Class
    

    Then your can use:

    For Each item As Object In exmp.results 'item will be a Dictionary(Of String, Object)
        For Each example As Object In item ' example will be a KeyValuePari(Of String, Object)
            Console.WriteLine(example.key)
            Console.WriteLine(example.value)
        Next
    Next
    

    Or by name like this:

        For Each item As Object In exmp.results 'item will be a Dictionary(Of String, Object)
            Console.WriteLine(item("message_id"))
            Console.WriteLine(item("errord"))
        Next
    Next