VB.NET如何反序列化嵌套数组格式的JSON字符串?
给定JSON字符串:
[[5389809,"*Bella*@",0,"",0,"","y",1],[9888723,"bizarre",0,"",0,"","y",1],[9889781,"violate",0,"",0,"","y",1],[1510819,"xeno",1,"",0,"","y",1]]
我尝试使用以下自定义对象类反序列化:
Public Class MyFriendsList Public Property Array() As List(Of CategoryContainer) End Class Public Class CategoryContainer Public Property id As Integer Public Property user As String End Class
但运行报错:
Newtonsoft.Json.JsonSerializationException: "Cannot deserialize the current JSON array (e.g. [1,2,3]) into type 'xMessenger.MyFriendsList' because the type requires a JSON object (e.g. {"name":"value"}) to deserialize correctly. To fix this error either change the JSON to a JSON object (e.g. {"name":"value"}) or change the deserialized type to an array or a type that implements a collection
错误根源
你的JSON是数组的数组(外层为数组,每个子元素也是包含8个值的有序数组),但你试图将其反序列化为带Array属性的MyFriendsList对象——这种结构要求JSON顶层是{"Array": [...]}格式的对象,和当前JSON的数组结构完全不匹配,因此序列化器抛出类型不匹配的错误。
解决思路
方法1:强类型反序列化(推荐)
修改CategoryContainer类,用JsonProperty特性指定属性对应JSON子数组的索引(因为JSON子数组是有序的,没有键名),然后直接反序列化为List(Of CategoryContainer):
Imports Newtonsoft.Json Public Class CategoryContainer <JsonProperty(Order := 0)> ' 对应子数组第1个元素(索引0) Public Property id As Integer <JsonProperty(Order := 1)> ' 对应子数组第2个元素(索引1) Public Property user As String ' 若需要后续字段,可按顺序添加对应属性 <JsonProperty(Order := 2)> Public Property Status1 As Integer <JsonProperty(Order := 3)> Public Property ExtraStr1 As String <JsonProperty(Order := 4)> Public Property Status2 As Integer <JsonProperty(Order := 5)> Public Property ExtraStr2 As String <JsonProperty(Order := 6)> Public Property Flag As String <JsonProperty(Order := 7)> Public Property Status3 As Integer End Class
反序列化代码:
Dim jsonContent = "[[5389809,""*Bella*@"",0,"""",0,"""",""y"",1],[9888723,""bizarre"",0,"""",0,"""",""y"",1],[9889781,""violate"",0,"""",0,"""",""y"",1],[1510819,""xeno"",1,"""",0,"""",""y"",1]]" Dim friendsList = JsonConvert.DeserializeObject(Of List(Of CategoryContainer))(jsonContent)
方法2:手动解析无类型数组
如果不需要完整强类型,可先反序列化为数组的数组,再手动提取所需字段:
Dim rawArray = JsonConvert.DeserializeObject(Of List(Of Object()))(jsonContent) Dim friendsList = New List(Of CategoryContainer)() For Each item In rawArray friendsList.Add(New CategoryContainer With { .id = CInt(item(0)), .user = CStr(item(1)) }) Next
方法3:保留MyFriendsList类的兼容方案
若必须使用MyFriendsList作为最终类型,可先反序列化为列表,再手动包装:
Dim innerList = JsonConvert.DeserializeObject(Of List(Of CategoryContainer))(jsonContent) Dim myFriendsList = New MyFriendsList With {.Array = innerList}
内容的提问来源于stack exchange,提问作者xeno

