我正在使用JSON.NET从HTTP查询反序列化JSON响应,但我遇到了问题。那是因为响应可以在同一属性下发送两种类型的对象,如下所示:
第一个案例样本(最常见):
{
"type": "myType",
"tid": 4,
"action": "myAction",
"method": "myMethod",
"result": {
"success": true,
"total": 4,
"records": [
{
"id": 4,
"nome": "PRIMEIRO NOME",
"sigla": "PN"
},
{
"id": 1974,
"nome": "SEGUNDO NOME",
"sigla": "SN"
},
{
"id": 2584,
"nome": "TERCEIRO NOME",
"sigla": "TN"
},
{
"id": 1170,
"nome": "QUARTO NOME",
"sigla": "QN"
}
]
}
}
第二案例样本(罕见):
{
"type": "myType",
"tid": 3,
"action": "myAction",
"method": "myMethod",
"result": [
{
"id": 4,
"nome": "PRIMEIRO NOME",
"sigla": "PN"
},
{
"id": 1974,
"nome": "SEGUNDO NOME",
"sigla": "SN"
},
{
"id": 2584,
"nome": "TERCEIRO NOME",
"sigla": "TN"
},
{
"id": 1170,
"nome": "QUARTO NOME",
"sigla": "QN"
}
]
}
我一直在使用这些类来接收第一种情况的数据:
Public Class Record
Public Property id As Integer
Public Property nome As String
Public Property sigla As String
End Class
Public Class Result
Public Property success As Boolean
Public Property total As Integer
Public Property records As Record()
End Class
Public Class Response
Public Property type As String
Public Property tid As Integer
Public Property action As String
Public Property method As String
Public Property result As Result
End Class
所以它在第一个案例JSON的反序列化时运行良好,声明如下:
Dim myResponse = JsonConvert.DeserializeObject(Of Response)(myJsonString)
但是,当收到第二种情况JSON时,它会创建响应类型的对象,在其属性结果中存储结果类型的对象,属性保持为空,我需要检索的数据因此而无处存储。
我认为我应该修改类Response,因此它可以用于这个不同的数据集,这样:
Public Class Response
Public Property type As String
Public Property tid As Integer
Public Property action As String
Public Property method As String
Public Property result As Result
Public Property resultRecords As Record()
End Class
那么问题是:如何在适合其类型(上面的第一个示例案例)或响应时告诉JsonConvert是否将数据存储在属性 Response.result 中.resultRecords 在第二种情况下?
谢谢!
答案 0 :(得分:3)
由于JSON的格式可能因同一属性而异,因此您需要一个自定义JsonConverter
来处理它。转换器可以读取受影响属性的JSON,确定其格式,然后适当地填充对象。以下是您需要的代码:
Public Class ResultConverter
Inherits JsonConverter
Public Overrides Function CanConvert(objectType As Type) As Boolean
Return objectType = GetType(Result)
End Function
Public Overrides Function ReadJson(reader As JsonReader, objectType As Type, existingValue As Object, serializer As JsonSerializer) As Object
Dim token As JToken = JToken.Load(reader)
Dim result As Result = New Result
If token.Type = JTokenType.Array Then
result.records = token.ToObject(Of Record())(serializer)
result.total = result.records.Length
result.success = True
Else
serializer.Populate(token.CreateReader(), result)
End If
Return result
End Function
Public Overrides ReadOnly Property CanWrite As Boolean
Get
Return False
End Get
End Property
Public Overrides Sub WriteJson(writer As JsonWriter, value As Object, serializer As JsonSerializer)
Throw New NotImplementedException
End Sub
End Class
要使用转换器,请在<JsonConverter>
类的result
属性中添加Response
属性:
Public Class Response
Public Property type As String
Public Property tid As Integer
Public Property action As String
Public Property method As String
<JsonConverter(GetType(ResultConverter))>
Public Property result As Result
End Class
这是一个工作小提琴,表明此转换器将允许将两种JSON格式反序列化为相同的类:https://dotnetfiddle.net/NFbQ2Q