What you can do is create a JsonConverter that serializes your Actor class as IEnumerable<object> in the correct order, then when deserializing it reads JSON using LINQ to JSON , checks that the token being read is an array, then sets the properties in an equivalent order.
You can hardcode this for your Actor class, but I think itβs more interesting to create a universal converter that converts the non-enumerable POCO from and into the JSON array using an order of properties of the POCO type. This order can be specified in your class using <JsonProperty(Order := NNN)> .
So, the converter:
Public Class ObjectToArrayConverter(Of T) Inherits JsonConverter Public Overrides Function CanConvert(objectType As Type) As Boolean Return GetType(T) = objectType End Function Private Shared Function ShouldSkip(p As JsonProperty) As Boolean Return p.Ignored Or Not p.Readable Or Not p.Writable End Function Public Overrides Sub WriteJson(writer As JsonWriter, value As Object, serializer As JsonSerializer) If value Is Nothing Then writer.WriteNull() Else Dim type = value.GetType() Dim contract = TryCast(serializer.ContractResolver.ResolveContract(type), JsonObjectContract) If contract Is Nothing Then Throw New JsonSerializationException("invalid type " & type.FullName) End If Dim list = contract.Properties.Where(Function(p) Not ShouldSkip(p)).Select(Function(p) p.ValueProvider.GetValue(value)) serializer.Serialize(writer, list) End If End Sub Public Overrides Function ReadJson(reader As JsonReader, objectType As Type, existingValue As Object, serializer As JsonSerializer) As Object If reader.TokenType = JTokenType.Null Then Return Nothing End If 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) End If 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) Next Return value End Function End Class
And your class:
<JsonConverter(GetType(ObjectToArrayConverter(Of Actor)))> _ Public Class Actor ' Use [JsonProperty(Order=x)] //http://www.newtonsoft.com/json/help/html/JsonPropertyOrder.htm to explicitly set the order of properties <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 End Class
Working violin .
Note that an updated version of C # that handles JsonConverter attributes applied to properties can be found here .
source share