在Visual Basic .NET中反序列化JSON

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在Visual Basic .NET中反序列化JSON相关的知识,希望对你有一定的参考价值。

想知道你是否可以帮助我创建一个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)),这是我现在拥有的?

答案

您可以做的是创建一个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

以上是关于在Visual Basic .NET中反序列化JSON的主要内容,如果未能解决你的问题,请参考以下文章

在 Visual Studio 中反序列化 JSON 文件时出错

如何在Visual Studio和CodeBlocks中反编译C++代码

在 .NET 中反序列化 Pokemon API

是否可以确定在 Json.Net 中反序列化了哪些属性? [复制]

如何在 asp.net 中反序列化 Json-Object

如何在 .NET 中反序列化为本地集合?