将 JSON 对象和数组转换为 VB.net 中的相同 class
Convert JSON object and array to same class in VB.net
我正在尝试将从第三方 API 返回的 JSON 转换为 VB.NET class 对象。问题是 JSON 有时 returns 一个节点作为对象数组,有时同一节点作为单个对象。因此,在接收到对象数组时尝试转换时,代码抛出异常。
{
"correlation_id": "228.9219622269229",
"Error": {
"messages": [
{
"code": "401",
"description": "Unauthorized"
}
]
},
"transaction_status": "Not Processed"
}
可以看到,在Error->messages节点下有一个错误信息数组。但有时,返回的 JSON 很简单,错误消息的对象类似于
{
"correlation_id": "228.9219622269229",
"Error": {
"messages": {
"code": "401",
"description": "Unauthorized"
}
},
"transaction_status": "Not Processed"
}
我尝试将此 JSON 反序列化为以下 class
Public Class PayeezyRefundResponse
Public correlation_id As String
Public transaction_status As String
Public validation_status As String
Public transaction_type As String
Public transaction_id As String
Public transaction_tag As String
Public bank_resp_code As String
Public bank_message As String
Public [Error] As PayeezyError
End Class
Public Class PayeezyError
Public messages As PayeezyErrorMessages()
End Class
Public Class PayeezyErrorMessages
Public code As String
Public description As String
End Class
但是当 JSON returns 错误消息作为单个对象时,代码会在 PayeezyError class 上抛出异常。我如何将 JSON 转换为 class 以便它在两种情况下都有效(即对象数组和单个对象)?
您可以构建一个可以处理这两种情况的自定义转换器 List(Of PayeezyErrorMessage)
.
此转换器始终 returns 一个 List(Of PayeezyErrorMessage)
,即使 JSON 包含单个对象。
注意:在代码中,PayeezyErrorMessages
,复数,已经重命名为PayeezyErrorMessage
,单数,因为这个class生成了单数目的。
自定义转换器作为属性添加到 属性:
<JsonConverter(GetType(PayeezyErrorsConverter(Of PayeezyErrorMessage)))>
Public Messages As List(Of PayeezyErrorMessage)
重构代码:
Public Class PayeezyRefundResponse
' [...]
<JsonProperty("Error")>
Public Errors As PayeezyErrors
End Class
Public Class PayeezyErrors
<JsonProperty("messages")>
<JsonConverter(GetType(PayeezyErrorsConverter(Of PayeezyErrorMessage)))>
Public Messages As List(Of PayeezyErrorMessage)
End Class
Public Class PayeezyErrorMessage
Public code As String
Public description As String
End Class
自定义转换器:
► 作者部分未实现,因为您可能不需要发回此 JSON
Imports Newtonsoft.Json
Imports Newtonsoft.Json.Linq
Public Class PayeezyErrorsConverter(Of T)
Inherits JsonConverter
Public Overrides Function CanConvert(objectType As Type) As Boolean
Return (objectType = GetType(List(Of T)))
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)
If token.Type = JTokenType.Array Then
Return token.ToObject(Of List(Of T))()
End If
Return New List(Of T)() From {
token.ToObject(Of T)()
}
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
我正在尝试将从第三方 API 返回的 JSON 转换为 VB.NET class 对象。问题是 JSON 有时 returns 一个节点作为对象数组,有时同一节点作为单个对象。因此,在接收到对象数组时尝试转换时,代码抛出异常。
{
"correlation_id": "228.9219622269229",
"Error": {
"messages": [
{
"code": "401",
"description": "Unauthorized"
}
]
},
"transaction_status": "Not Processed"
}
可以看到,在Error->messages节点下有一个错误信息数组。但有时,返回的 JSON 很简单,错误消息的对象类似于
{
"correlation_id": "228.9219622269229",
"Error": {
"messages": {
"code": "401",
"description": "Unauthorized"
}
},
"transaction_status": "Not Processed"
}
我尝试将此 JSON 反序列化为以下 class
Public Class PayeezyRefundResponse
Public correlation_id As String
Public transaction_status As String
Public validation_status As String
Public transaction_type As String
Public transaction_id As String
Public transaction_tag As String
Public bank_resp_code As String
Public bank_message As String
Public [Error] As PayeezyError
End Class
Public Class PayeezyError
Public messages As PayeezyErrorMessages()
End Class
Public Class PayeezyErrorMessages
Public code As String
Public description As String
End Class
但是当 JSON returns 错误消息作为单个对象时,代码会在 PayeezyError class 上抛出异常。我如何将 JSON 转换为 class 以便它在两种情况下都有效(即对象数组和单个对象)?
您可以构建一个可以处理这两种情况的自定义转换器 List(Of PayeezyErrorMessage)
.
此转换器始终 returns 一个 List(Of PayeezyErrorMessage)
,即使 JSON 包含单个对象。
注意:在代码中,PayeezyErrorMessages
,复数,已经重命名为PayeezyErrorMessage
,单数,因为这个class生成了单数目的。
自定义转换器作为属性添加到 属性:
<JsonConverter(GetType(PayeezyErrorsConverter(Of PayeezyErrorMessage)))>
Public Messages As List(Of PayeezyErrorMessage)
重构代码:
Public Class PayeezyRefundResponse
' [...]
<JsonProperty("Error")>
Public Errors As PayeezyErrors
End Class
Public Class PayeezyErrors
<JsonProperty("messages")>
<JsonConverter(GetType(PayeezyErrorsConverter(Of PayeezyErrorMessage)))>
Public Messages As List(Of PayeezyErrorMessage)
End Class
Public Class PayeezyErrorMessage
Public code As String
Public description As String
End Class
自定义转换器:
► 作者部分未实现,因为您可能不需要发回此 JSON
Imports Newtonsoft.Json
Imports Newtonsoft.Json.Linq
Public Class PayeezyErrorsConverter(Of T)
Inherits JsonConverter
Public Overrides Function CanConvert(objectType As Type) As Boolean
Return (objectType = GetType(List(Of T)))
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)
If token.Type = JTokenType.Array Then
Return token.ToObject(Of List(Of T))()
End If
Return New List(Of T)() From {
token.ToObject(Of T)()
}
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