在Visual Basic .NET中反序列化JSON [英] Deserializing JSON in Visual Basic .NET
问题描述
想知道是否可以帮助我创建一个VB.Net类,可以在其中反序列化以下JSON响应:
Wondering if you could help me create a VB.Net class into which I can deserialize the following JSON response:
{
"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反序列化:
I am using Newtonsoft.Json to deserialize:
Result = Newtonsoft.Json.JsonConvert.DeserializeObject(Of Player)(jsonResponse)
如果我知道actor元素始终遵循相同的格式-
If I know that the actors elements always follow the same format -
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))?
Is there a way I can parse the JSON response so that Player.Likes.Actors is a List(Of Actor) instead of a List(Of List(Of String)) which is what I have now?
推荐答案
您可以做的是创建 JsonConverter
,将您的Actor
类以正确的顺序序列化为IEnumerable<object>
,然后在反序列化中使用
What you can do is to create a JsonConverter
that serializes your Actor
class as an IEnumerable<object>
in the correct order, then in deserialization reads the JSON using LINQ to JSON, checks that the token read is an array, then sets the properties in the equivalent order.
您可以为Actor
类对此进行硬编码,但是我认为创建一个通用转换器会更有趣,该通用转换器使用POCO类型的属性顺序将不可枚举的POCO往返于JSON数组.可以在您的班级中使用 <JsonProperty(Order := NNN)>
属性指定此顺序
You could hardcode this for your Actor
class, but I think it's more interesting to create a generic converter that converts non-enumerable POCO from and to a JSON array using the POCO type's property order. This order can be specified in your class using the <JsonProperty(Order := NNN)>
attribute.
因此,转换器:
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
工作小提琴.
请注意,可以在此处找到更新的c#版本,该版本可以处理应用于属性的JsonConverter
属性.
Note an updated c# version that handles JsonConverter
attributes applied to properties can be found here.
这篇关于在Visual Basic .NET中反序列化JSON的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!