json - 如何使用 Json.Net 反序列化嵌套的 JSON 数组?
问题描述
我想反序列化 HTTP 请求对对象的响应。
响应如下所示:
[
"BeginOfEnumerable",
[
{
"StatusID": 12345,
"ItemID": 987654
}
],
"EndOfEnumerable"
]
我正在使用 Newtonsoft.Json。
我尝试使用 Visual StudioEdit > Paste special > Paste JSON as Classes
创建类模型,但结果对我来说看起来很奇怪:
Public Class Rootobject
Public Property Property1() As Object
End Class
此外,这会引发异常:
Dim myObject As Rootobject = JsonConvert.DeserializeObject(response.Content)
» 解析值时遇到意外字符:.Path ",第 0 行,第 0 位置。
我想得到StatusID
and ItemID
。
我使用的 JSON Validator 说这个 JSON 是有效的。
解决方案
JSON 结构本身是有效的,对于不遵循该name:value
模式的字符串,您可能会遇到一些困难。
您只能反序列化值的内部数组List(class)
,例如,
Imports System.Collections.Generic
Imports Newtonsoft.Json
Imports Newtonsoft.Json.Linq
Public Class EnumObject
Public Property StatusId As Long
Public Property ItemId As Long
End Class
'[...]
Dim jsonEnumsTokens = JArray.Parse(response.Content)
Dim enumsArray = jsonEnumsTokens.Children.Skip(1).First().ToObject(Of List(Of EnumObject))()
它返回EnumObject
包含值的列表,如果这就是您感兴趣的全部并且您不需要以任何其他方式处理此 JSON,或者以相同的形式将其序列化回。
如果您只想获取数组的 JSON 表示形式:
Dim justTheArraysJson = jsonEnumsTokens.Children.Skip(1).First().ToString()
如果您想执行反序列化和序列化,维护结构,您可以使用处理这种情况的自定义 JsonConverter 。
EnumObjectsConverter
创建一个中间结构,其中包含EnumObjectArray
属性中包含的单个字符串和值数组。
如果需要,这也允许序列化回原始结构。
称它为:
Dim enumArray = EnumObjectsHandler.Deserialize(response.Content)
Dim serialized = EnumObjectsHandler.Serialize(enumArray)
为序列化提供静态方法的EnumObjectsHandler
类:
Public Class EnumObjectsHandler
Private Shared settings As JsonSerializerSettings = New JsonSerializerSettings() With {
.Converters = {New EnumObjectsConverter()}
}
Public Shared Function Deserialize(json As String) As List(Of EnumObjectsRoot)
Return JsonConvert.DeserializeObject(Of List(Of EnumObjectsRoot))(json, settings)
End Function
Public Shared Function Serialize(data As List(Of EnumObjectsRoot)) As String
Return JsonConvert.SerializeObject(data, settings)
End Function
Public Class EnumObject
Public Property StatusId As Long
Public Property ItemId As Long
End Class
Public Structure EnumObjectsRoot
Public Property EnumObjectArray As List(Of EnumObject)
Public Property Operation As String
Public Shared Widening Operator CType(objectArray As List(Of EnumObject)) As EnumObjectsRoot
Return New EnumObjectsRoot With {.EnumObjectArray = objectArray}
End Operator
Public Shared Widening Operator CType(op As String) As EnumObjectsRoot
Return New EnumObjectsRoot With {.Operation = op}
End Operator
End Structure
Friend Class EnumObjectsConverter
Inherits JsonConverter
Public Overrides Function CanConvert(t As Type) As Boolean
Return t Is GetType(EnumObjectsRoot)
End Function
Public Overrides Function ReadJson(reader As JsonReader, t As Type, existingValue As Object, serializer As JsonSerializer) As Object
Select Case reader.TokenType
Case JsonToken.String
Dim stringValue = serializer.Deserialize(Of String)(reader)
Return New EnumObjectsRoot() With {
.Operation = stringValue
}
Case JsonToken.StartArray
Dim arrayValue = serializer.Deserialize(Of List(Of EnumObject))(reader)
Return New EnumObjectsRoot() With {
.EnumObjectArray = arrayValue
}
End Select
Throw New Exception("EnumObjectsRoot could not be deserialized")
End Function
Public Overrides Sub WriteJson(writer As JsonWriter, untypedValue As Object, serializer As JsonSerializer)
Dim value = CType(untypedValue, EnumObjectsRoot)
If value.Operation IsNot Nothing Then
serializer.Serialize(writer, value.Operation)
Return
End If
If value.EnumObjectArray IsNot Nothing Then
serializer.Serialize(writer, value.EnumObjectArray)
Return
End If
Throw New Exception("EnumObjectsRoot could not be serialized")
End Sub
End Class
End Class
推荐阅读
- go - 弃用和撤回之间的区别?
- python - 并行处理数千个文件
- javascript - 带有 @fingerprintjs/fingerprintjs 的角 ssr
- javascript - 使用 javascript 创建元素,可以通过循环将其放入 HTML 元素中
- reactjs - 如何
- python - FastAPI Alembic - migrations files are not being created even though output says so. Folder "versions" is empty, and tables are missing from database
- javascript - GTM custom javascript is not working, what to do?
- python - How can you edit multiple legend boxes in a seanborn scatter plot?
- github - 拉码时个人访问令牌未验证失败
- postgresql - postgres中带有链中参数的递归查询