想知道你是否可以帮我创建一个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)
如果我知道演员元素总是遵循相同的格式 -
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(Of List(Of String)),这是我现在拥有的?
答案 0 :(得分:0)
您可以做的是创建一个JsonConverter
,按照正确的顺序将Actor
类序列化为IEnumerable<object>
,然后在反序列化中使用LINQ to JSON读取JSON,检查令牌读取是否为数组,然后按等效顺序设置属性。
您可以为Actor
课程对此进行硬编码,但我认为创建一个通用转换器更有意义,该转换器使用POCO类型将不可枚举的POCO转换为JSON数组。物业订单。您可以使用<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
工作fiddle。