在Visual Basic .NET中反序列化JSON [英] Deserializing JSON in Visual Basic .NET

查看:69
本文介绍了在Visual Basic .NET中反序列化JSON的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

想知道是否可以帮助我创建一个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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆