I have a recursive data structure. Something like…
Public Class Comparison
Property Id As Integer
End Class
Public Class SimpleComparison
Inherits Comparison
Property Left As String
Property Right As String
End Class
Public Class ComplexComparison
Inherits Comparison
Property Left As Comparison
Property Right As Comparison
End Class
I need to deserialize to this from JSON.
As you can see, the only way to determine whether to use a ComplexComparison or a SimpleComparison is by determining if the .Left value is a string or an object. (NB They’ll either both be string or both object)
So, I’m writing a custom converter and have got this far…
Public Class ComparisonConverter
Inherits Newtonsoft.Json.JsonConverter
''<Snip>
Public Overrides Function ReadJson(reader As Newtonsoft.Json.JsonReader, objectType As Type, existingValue As Object, serializer As Newtonsoft.Json.JsonSerializer) As Object
Dim obj As JObject = TryCast(serializer.Deserialize(Of JToken)(reader), JObject)
If obj IsNot Nothing Then
''We''ve got something to work with
Dim Id As Integer = obj("Id").ToObject(Of Integer)()
''Check if we''re instantiating a simple or a complex comparison
If obj("Left").GetType.IsAssignableFrom(GetType(JValue)) Then
''LHS is a string - Simple...
Return New SimpleComparison With {
.Id = Id,
.Left = obj("Left").ToObject(Of String)(),
.Right = obj("Right").ToObject(Of String)()}
Else
Return New ComplexComparison With {
.Id = Id,
.Left = ???, '' <<Problem
.Right = ???}'' <<Problem
End If
Else
Return Nothing
End If
End Function
End Class
The branch of the If that results from the object being complex is where I get stuck. How can I re-invoke the deserializer on the obj("Left") and obj("Right") (which are of type JToken) ? Or should I Cast them to JObject and then factor this code out into a seperate function and recursively call that?
It turned out to be simpler than I expected and JSON.Net does all the heavy lifting for me…