【发布时间】:2020-08-10 11:48:01
【问题描述】:
我收到以下格式的 JSON 格式的 API 响应
{
"stuffs": {
"prop1": "abcd",
"prop2": "efgh",
"prop3": [
{
"content": "123456",
"name": "abc def",
"id": "123"
},
{
"content": "789012",
"name": "def ghi",
"id": "456"
}
]
}
}
我已经创建了我的类来反序列化这个对象,如下所示
Public Class Prop3
Public Property content As String
Public Property name As String
Public Property id As String
End Class
Public Class Stuffs
Public Property prop1 As String
Public Property prop2 As String
Public Property prop3 As Prop3()
End Class
Public Class Example
Public Property stuffs As Stuffs
End Class
现在的问题是,有时响应不是 prop3 的数组,看起来像这样
{
"stuffs": {
"prop1": "abcd",
"prop2": "efgh",
"prop3": {
"content": "123456",
"name": "abc def",
"id": "123"
}
}
}
这次我在反序列化时出错,因为 prop3 不再是数组,而是在我的类材料中声明的属性需要一个属性 prop3 的数组。
有没有动态的方法来解决这个问题?就像 JSON 响应是一个数组一样,它将被视为数组
Public Property prop3 As Prop3()
如果它不是一个数组,那么它将被视为单个属性
Public Property prop3 As Prop3
请建议如何克服这个问题,因为更改 API 的响应是不可行的,因为它是由客户端开发的,我需要在我的应用程序中使用它,所以我需要找到一些动态的方法来解决这个问题。
根据Craig的建议,我尝试了以下方法,但仍然没有发生,如果我犯了任何错误,请提出建议。
Public Class SingleValueArrayConverter(Of T)
Inherits JsonConverter
Public Overrides Sub WriteJson(ByVal writer As JsonWriter, ByVal value As Object, ByVal serializer As JsonSerializer)
serializer.Serialize(writer, value)
End Sub
Public Overrides Function ReadJson(ByVal reader As JsonReader, ByVal objectType As Type, ByVal existingValue As Object, ByVal serializer As JsonSerializer) As Object
Dim retVal As Object = New Object()
If reader.TokenType = JsonToken.StartObject Then
Dim instance As T = CType(serializer.Deserialize(reader, GetType(T)), T)
retVal = New List(Of T)() From {
instance
}
ElseIf reader.TokenType = JsonToken.StartArray Then
retVal = serializer.Deserialize(reader, objectType)
End If
Return retVal
End Function
Public Overrides Function CanConvert(ByVal objectType As Type) As Boolean
Return True
End Function
End Class
Public Class myClass1
Public Class Prop3
Public Property content As String
Public Property name As String
Public Property id As String
End Class
Public Class Stuffs
Public Property prop1 As String
Public Property prop2 As String
<JsonProperty("prop3")>
<JsonConverter(GetType(SingleValueArrayConverter(Of Prop3)))>
Public Property prop3 As Prop3()
End Class
Public Class Example
Public Property stuffs As Stuffs
End Class
End Class
它给出错误: 无法将类型为“SingleValueArrayConverter`1[myClass1.myClass+Prop3]”的对象转换为类型“Newtonsoft.Json.JsonConverter”。
请强调一下我所缺少的。
【问题讨论】:
-
懒惰的方式...将
Prop3声明为Object,然后您可以在准备好使用它时键入检查并进行相应的转换(检查对象类型是否为数组)。或者,制作一个自定义反序列化器,将单个实例放入数组中,因此当您访问它时,您始终将其视为数组。 -
我正在使用 Newtonsoft 的 JsonConvert.DeserializeObject。如何制作自定义反序列化器?也不明白“将 Prop3 声明为对象”,因为 prop3 是 Prop3 类的对象。你能强调一下吗?
-
这不是一个新问题。您需要创建一个自定义类来实现
JsonConverter接口并将标量对象转换为长度为 1 的数组或列表(“写入”函数则相反)。 -
嗨,克雷格,我对这个概念还很陌生,对此知之甚少,请您提供更多说明。
-
@MeghdutSaha Craig 发布的链接已经包含很多插图......
标签: json vb.net deserialization json-deserialization