Imports Newtonsoft.Json.Linq
Imports Newtonsoft.Json.Converters
Imports Newtonsoft.Json.Serialization
<JsonConverter(GetType(ObjectToArrayConverter(Of Actor)))> _
Public Readonly Property AReadOnlyNumber() As Integer
Return NumberOfMovies + NumberOfAwards + NumberOfTVshows
<JsonProperty(Order := 0)> _
Public Property Name As String
<JsonProperty(Order := 1)> _
Public Property NumberOfMovies As Integer
<JsonProperty(Order := 2)> _
Public Property NumberOfAwards As Integer
<JsonProperty(Order := 3)> _
Public Property NumberOfTVshows As Integer
Public Class ObjectToArrayConverter(Of T)
Public Overrides Function CanConvert(objectType As Type) As Boolean
Return GetType(T) = objectType
Private Shared Function ShouldSkip(p As JsonProperty) As Boolean
Return p.Ignored Or Not p.Readable Or Not p.Writable
Public Overrides Sub WriteJson(writer As JsonWriter, value As Object, serializer As JsonSerializer)
Dim type = value.GetType()
Dim contract = TryCast(serializer.ContractResolver.ResolveContract(type), JsonObjectContract)
If contract Is Nothing Then
Throw New JsonSerializationException("invalid type " & type.FullName)
Dim list = contract.Properties.Where(Function(p) Not ShouldSkip(p)).Select(Function(p) p.ValueProvider.GetValue(value))
serializer.Serialize(writer, list)
Public Overrides Function ReadJson(reader As JsonReader, objectType As Type, existingValue As Object, serializer As JsonSerializer) As Object
If reader.TokenType = JTokenType.Null Then
Dim token = JArray.Load(reader)
Dim contract = TryCast(serializer.ContractResolver.ResolveContract(objectType), JsonObjectContract)
If contract Is Nothing Then
Throw New JsonSerializationException("invalid type " & objectType.FullName)
Dim value = If(existingValue, contract.DefaultCreator()())
For Each pair In contract.Properties.Where(Function(p) Not ShouldSkip(p)).Zip(token, Function(p, v) New With { Key.Value = v, Key.Property = p })
Dim propertyValue = pair.Value.ToObject(pair.Property.PropertyType, serializer)
pair.Property.ValueProvider.SetValue(value, propertyValue)
Dim actor = New Actor() With { _
Dim json = JsonConvert.SerializeObject(actor, Formatting.Indented)
Dim actor2 = JsonConvert.DeserializeObject(Of Actor)(json)
If actor.Name <> actor2.Name OrElse actor.NumberOfMovies <> actor2.NumberOfMovies OrElse actor.NumberOfAwards <> actor2.NumberOfAwards OrElse actor.NumberOfTVshows <> actor2.NumberOfTVshows Then
Throw New InvalidOperationException()
Console.WriteLine(JsonConvert.SerializeObject(actor2, Formatting.Indented))