Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/json/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Visual Basic.NET中反序列化JSON_Json_Vb.net_Serialization_Json.net - Fatal编程技术网

在Visual Basic.NET中反序列化JSON

在Visual Basic.NET中反序列化JSON,json,vb.net,serialization,json.net,Json,Vb.net,Serialization,Json.net,不知您是否可以帮助我创建一个VB.Net类,我可以将以下JSON响应反序列化到该类中: { "id":86, "name":"Tom", "likes": { "actors":[ ["Clooney",2,30,4], ["Hanks",104,15,1] ] }, "code":8 } 我有以下资料: Cl

不知您是否可以帮助我创建一个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

如果我知道actors元素总是遵循相同的格式-

Class Actor
  Public Name as String
  Public NumberOfMovies as Integer
  Public NumberOfAwards as Integer
  Public NumberOfTVshows as Integer
End Class 

有没有一种方法可以解析JSON响应,使Player.Likes.Actors是一个列表(Actor的列表),而不是我现在拥有的列表(List(String的列表))?

您可以做的是创建一个以正确顺序将
Actor
类序列化为
IEnumerable
,然后在反序列化中使用,检查读取的令牌是否为数组,然后按等效顺序设置属性

您可以为
Actor
类硬编码,但我认为更有趣的是创建一个通用转换器,使用POCO类型的属性顺序将不可枚举的POCO从JSON数组转换为JSON数组。可以使用属性在类中指定此顺序

因此,转换器:

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
_
公共级演员
'使用[JsonProperty(Order=x)]//http://www.newtonsoft.com/json/help/html/JsonPropertyOrder.htm 显式设置属性顺序的步骤
_
作为字符串的公共属性名称
_
公共属性numberOfAsInteger
_
公共财产数为整数
_
公共属性NumberOfTVshows显示为整数
末级
工作


注意:可以找到处理应用于属性的
JsonConverter
属性的更新c#版本。

您可以做的是创建一个将您的
Actor
类序列化为
IEnumerable
的类,然后在反序列化过程中使用,然后按等效顺序设置属性

您可以为
Actor
类硬编码,但我认为更有趣的是创建一个通用转换器,使用POCO类型的属性顺序将不可枚举的POCO从JSON数组转换为JSON数组。可以使用属性在类中指定此顺序

因此,转换器:

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
_
公共级演员
'使用[JsonProperty(Order=x)]//http://www.newtonsoft.com/json/help/html/JsonPropertyOrder.htm 显式设置属性顺序的步骤
_
作为字符串的公共属性名称
_
公共属性numberOfAsInteger
_
公共财产数为整数
_
公共属性NumberOfTVshows显示为整数
末级
工作


请注意,可以找到一个更新的c版本,该版本处理应用于属性的
JsonConverter
属性。

实际上,
Actors
看起来像一个
对象。每个actor项都有一个相同的字符串,但是还有3个int。它们没有“命名”,所以问题是让它们映射到任何有意义的东西。如果您只需要名称,您可以对其进行解析并将其搜索出来。实际上,
Actors
看起来像一个
对象。每个actor项都有一个相同的字符串,但是还有3个int。它们没有“命名”,所以问题是让它们映射到任何有意义的东西。如果你想要的只是名字,你可以解析它并把它们钓出来。这很好,非常感谢你的详细回复。我现在在实现上面的代码时遇到的问题是转换器中的行:Dim propertyValue=pair.Value.ToObject(pair.Property.PropertyType,serializer)。。。。我得到错误:“重载解析失败,因为没有可访问的'ToObject'接受此数量的参数”。有什么想法吗?@Freemo-我正在使用当前版本的Json.NET中提供的内容(而且似乎早在Json.NET 4.5.11中就有)。你可以更新你的问题来显示你的代码,或者把它上传到某个地方的粘贴库中吗?转换器正在.I更新为最新版本的Json.NET中工作,并且工作得非常好。你真是个天才!非常感谢,你救了我的周末。这太好了,非常感谢你的详细回复。我现在在实现上面的代码时遇到的问题是转换器中的行:Dim propertyValue=pair.Value.ToObject(pair.Property.PropertyType,serializer)。。。。我得到错误:“重载解析失败,因为没有可访问的'ToObject'接受此数量的参数”。有什么想法吗?@Freemo-我正在使用当前版本的Json.NET中提供的内容(而且似乎早在Json.NET 4.5.11中就有)。你可以更新你的问题来显示你的代码,或者把它上传到某个地方的粘贴库中吗?转换器正在.I更新为最新版本的Json.NET中工作,并且工作得非常好。你真是个天才!非常感谢,你救了我的周末。祝你一切顺利