vb.NET Deserialise JSON list into object

18,951

Your JSON string represents an array of objects (you can see this because everything is wrapped between [ and ]).

The error message is saying "you tried to deserialize an array of objects into a single object". Your target type GeneralArray does not behave like an array (e.g. it does not inherit from an array/collection type nor does it implement a collection interface).

The other issue is, the JSON array is "mixed" - it contains some objects that look like ItemDetails and other objects that look like ItemArray. In a static language like VB.NET, this is more difficult to deserialize into a single collection of distinct types.

One possible solution is to combine your target classes ItemDetails and ItemArray into a single class, along the lines of

Public Class CombinedItem
    'properties from ItemDetails
    Public Value As Integer
    Public Text As String

    'properties from ItemArray
    Public InnerList As List(Of CombinedItem)
    Public Duplicated As String

End Class

Given this class, your deserialization might look like:

Dim JSONObj = JsonConvert.DeserializeObject(Of List(Of CombinedItem))(JSONString)

The key here is you telling Newtonsoft that the target type is a List(Of CombinedItem) - an array/collection like target.

Now JSONObj is a collection of the CombinedItem - some will have a Value/Text property, others will have a InnerList/Duplicated property.

Share:
18,951
Your_Unequal
Author by

Your_Unequal

Updated on June 08, 2022

Comments

  • Your_Unequal
    Your_Unequal almost 2 years

    I've not quite been able to find the exact answer for which I'm looking so thought I'd have a crack at asking the question.

    I'm currently attempting to deserialise a JSON string into an object in vb.NET using Json.NET; I've done a few before by setting up appropriate Classes and then deserialising the string to an object using the Parent Class and they've worked fine however this one just doesn't seem to break down quite right.

    An example of the string I'm trying to break down is as follows:

       [
        {
            "value": 12345,
            "text": "Example Unique Text"
        },
        {
            "InnerList": [
                {
                    "value": 4746,
                    "text": "A duplicated entry of text"
                },
                {
                    "value": 4747,
                    "text": "A duplicated entry of text"
                },
                {
                    "value": 4748,
                    "text": "A duplicated entry of text"
                },
                {
                    "value": 4749,
                    "text": "A duplicated entry of text"
                },
                {
                    "value": 4750,
                    "text": "A duplicated entry of text"
                },
                {
                    "value": 4751,
                    "text": "A duplicated entry of text"
                },
                {
                    "value": 4752,
                    "text": "A duplicated entry of text"
                },
                {
                    "value": 4753,
                    "text": "A duplicated entry of text"
                },
                {
                    "value": 4754,
                    "text": "A duplicated entry of text"
                },
                {
                    "value": 4755,
                    "text": "A duplicated entry of text"
                }
            ],
            "duplicated": "Yes"
        },
        {
            "value": 15298,
            "text": "Another Example Unique Text"
        },
        {
            "value": 959,
            "text": "Yet more uniqueness"
        },
        {
            "value": 801,
            "text": "A final little bit of unique text"
        }
    ]
    

    I've tried passing this through a number of external tools and they all come back with the same Class definitions however they haven't seemed to work. So based on my understanding of JSON I put together the following:

     Public Class ItemDetails
    
            Public Value As Integer
            Public Text As String
    
     End Class
    
     Public Class ItemArray
    
            Public DetailList As List(Of ItemDetails)
            Public Duplicated As String
    
     End Class
    
     Public Class GeneralArray
    
            Public GeneralList As List(Of ItemArray)
    
     End Class
    

    GeneralArray is the Parent Class and is what's being used to parse the JSON.

    I'm then trying to deserialise the string to the Parent Class. In the following example, is the JSON String outlined above and JSONStringCollection is the Module in which GeneralArray is defined:

    Dim JSONString As String
    
    JSONString = "<JSONStringDetails>"
    
    Dim JSONObj = JsonConvert.DeserializeObject(Of JSONStringCollection.GeneralArray)(JSONString)
    

    Sadly, when passing this through, the following is returned and the routine breaks:

    An unhandled exception of type 'Newtonsoft.Json.JsonSerializationException' occurred in Newtonsoft.Json.dll

    Additional information: Cannot deserialize the current JSON array (e.g. [1,2,3]) into type 'ShadOS.JSONStringCollection+GeneralArray' because the type requires a JSON object (e.g. {"name":"value"}) to deserialize correctly.

    What am I missing with this?