2

I have a JSON string that I am trying to deserialize to a .Net object.

The code works, until it hits a nested array. Then it just returns empty values.
In the below example, when I debug and view the processed object, it will just have:

Rules:

0:  Will contain all data for the first node (project_number)  
1:  Will contain all data for the second node (agreement_number)  
2:  All fields will be Nothing  

Condition: AND  
Valid: true  

How do I deserialize the entire object? Please note, the JSON string comes from a library (https://querybuilder.js.org/) so I am hesitant to muck around with how the string is created.

Here is my code:

 Dim TestObj = JsonConvert.DeserializeObject(Of List(Of JsonObject))(TestString)

<Serializable()>
Public Class JsonObject
    Public Property condition As String
    Public Property Rules As List(Of Rules)
    Public Property valid As Boolean
End Class

<Serializable()>
Public Class Rules
    Public Property id As String
    Public Property field As String
    Public Property type As String
    Public Property input As String
    Public Property [operator] As String
    Public Property value As String
End Class

Public Property TestString As String = "[
{
   'condition':'AND',
   'rules':[
      {
         'id':'project_number',
         'field':'project_number',
         'type':'string',
         'input':'text',
         'operator':'equal',
         'value':'dfgdfs'
      },
      {
         'id':'agreement_number',
         'field':'agreement_number',
         'type':'string',
         'input':'text',
         'operator':'contains',
         'value':'asdfas'
      },
      {
         'condition':'AND',
         'rules':[
            {
               'id':'division',
               'field':'division',
               'type':'string',
               'input':'select',
               'operator':'in',
               'value':[
                  '0',
                  '11719'
               ]
            },
            {
               'condition':'AND',
               'rules':[
                  {
                     'id':'ta',
                     'field':'ta',
                     'type':'string',
                     'input':'select',
                     'operator':'in',
                     'value':[
                        '24740',
                        '24744'
                     ]
                  }
               ]
            }
         ]
      }
   ],
   'valid':true
}]"
Jimi
  • 29,621
  • 8
  • 43
  • 61
jason
  • 3,821
  • 10
  • 63
  • 120

1 Answers1

2

As described, you need to add a class that handles the nested Rules objects.
In you original class structure, the Rules class doesn't have a rules Property that can hold a second level of nesting.
But you also need to handle an undetermined level of nesting, since other nested classes can have further nested Rules object.

You can add a new class that handles this kind of nesting by referencing itself:

Partial Public Class RulesList
    Public Id As String
    Public Value As Long()
    '(...)
    Public Rules As RulesList()
End Class

Plus, it must hold an array/list of Value objects.

Note that I have used Arrays instead of Lists: it's just easier to inspect the results, you can use a List(Of [Type]) if you prefer, the final output doesn't change.


This sample class (named Queries), implements this kind of structure.
It also includes the Serialization and Deserialization (simplified, no error checking/handling) as static (shared) methods.

Assume jsonInput is your JSON object:

Deserialize to a List(Of QueryBuilder):

Dim myQueries = Queries.Deserialize(jsonInput)

Serialize a List(Of QueryBuilder) back to the original JSON object.
Note, using the JSON visualizer in Visual Studio, that the structure is reproduced exactly as the original:

Dim jsonOutput = Queries.Serialize(myQueries)

The Queries class:

Imports Newtonsoft.Json

Public Class Queries
    Public Class QueryBuilder
        Public Condition As String
        Public Rules As Rules()
        Public Valid As Boolean
    End Class

    Public Class Rules
        Public Id As String
        Public Field As String
        <JsonProperty("type")>
        Public QueryType As String
        Public Input As String
        <JsonProperty("operator")>
        Public QueryOperator As String
        Public Value As String
        Public Condition As String
        Public Rules As RulesList()
    End Class
    Partial Public Class RulesList
        Public Id As String
        Public Field As String
        <JsonProperty("type")>
        Public QueryType As String
        Public Input As String
        <JsonProperty("operator")>
        Public QueryOperator As String
        Public Value As Long()
        Public Condition As String
        Public Rules As RulesList()
    End Class

    Public Shared Function Deserialize(jsonSource As String) As List(Of QueryBuilder)
        Return JsonConvert.DeserializeObject(Of List(Of QueryBuilder))(jsonSource)
    End Function

    Public Shared Function Serialize(classObject As List(Of QueryBuilder)) As String
        Return JsonConvert.SerializeObject(classObject)
    End Function

End Class
Jimi
  • 29,621
  • 8
  • 43
  • 61