想知道您是否可以帮助我创建一个VB.Net类,在其中可以反序列化以下JSON响应:
{ "id":86, "name":"Tom", "likes": { "actors":[ ["Clooney",2,30,4], ["Hanks",104,15,1] ] }, "code":8 }
我有以下几点:
Class mLikes Public actors As IList(Of IList(Of String)) end Class
和
Class Player <JsonProperty(PropertyName:="id")> Public Id As Integer <JsonProperty(PropertyName:="name")> Public Name As String <JsonProperty(PropertyName:="likes")> Public Likes As mLikes <JsonProperty(PropertyName:="code")> Public Code As Integer End Class
我正在使用Newtonsoft.Json反序列化:
Result = Newtonsoft.Json.JsonConvert.DeserializeObject(Of Player)(jsonResponse)
如果我知道actor元素始终遵循相同的格式-
Class Actor Public Name as String Public NumberOfMovies as Integer Public NumberOfAwards as Integer Public NumberOfTVshows as Integer End Class
有没有一种方法可以解析JSON响应,以便Player.Likes.Actors是一个List(Of Actor)而不是我现在拥有的List(OfList(Of String))?
您可以做的是创建一个JsonConverter,以正确的顺序将您的Actor类序列化为IEnumerable<object>,然后在反序列化中使用LINQ to JSON读取JSON,检查所读取的令牌是否为数组,然后以等效顺序设置属性。
JsonConverter
Actor
IEnumerable<object>
您可以为您的Actor类对此进行硬编码,但是我认为创建一个通用转换器会更有趣,该通用转换器使用POCO类型的属性顺序将不可枚举的POCO往返于JSON数组。可以使用<JsonProperty(Order := NNN)>属性在您的班级中指定此顺序。
<JsonProperty(Order := NNN)>
因此,转换器:
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
和你的班级:
<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
工作提琴。
请注意,JsonConverter可以在此处找到处理适用于属性的属性的更新的c#版本。