You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

VB.NET中Newtonsoft.Json反序列化JSON数组集合报错咨询

VB.NET中Newtonsoft.Json反序列化JSON的错误修复与性能优化

问题描述

使用Newtonsoft.Json在VB.NET中反序列化JSON时抛出以下错误:

Newtonsoft.Json.JsonSerializationException:
'Cannot deserialize the current JSON object (e.g. {"name":"value"})
into type 'System.Collections.Generic.List`1[]' because the type
requires a JSON array (e.g. [1,2,3]) to deserialize correctly. To fix
this error either change the JSON to a JSON array (e.g. [1,2,3]) or
change the deserialized type so that it is a normal .NET type (e.g.
not a primitive type like integer, not a collection type like an array
or List) that can be deserialized from a JSON object.
JsonObjectAttribute can also be added to the type to force it to
deserialize from a JSON object.

目前通过循环调用多个selectToken实现功能,但性能较差,需要优化。

现有类定义

Public Class Orders
    Public recordSetTotal As Integer

    Public Class ordersList 'orders list is an array in the JSON data source
        Public Class orderDetails
            Public grandTotal As Single
            Public placedDate As String
        End Class
    
        Public Class address
            Public postcode As String
            Public addressLine() As String 'this is an array in the JSON data source
        End Class
    End Class
End Class

当前反序列化代码

'orderData is the JSON string block
Dim ordersList As List(Of Orders) = JsonConvert.DeserializeObject(Of List(Of Orders))(orderData)

示例JSON数据

{
   "recordSetTotal":10,
   "ordersList":[
      {
         "orderDetails":{
            "grandTotal":50.0000,
            "placedDate":"2022-12-25 12:00:00.000"
         },
         "addressLine":[
            "123 Fake St",
            "Somewhere",
            "ABG"
         ]
      }
   ]
}

解决方案

1. 类结构必须调整:修正嵌套关系

现有类结构和JSON数据完全不匹配,这是反序列化失败的核心原因:

  • JSON根对象是一个包含recordSetTotal和ordersList数组的单个对象,而非List(Of Orders)数组
  • 原Orders类中的ordersList是嵌套类,但JSON里ordersList是数组,每个元素包含orderDetails和addressLine,不存在单独的address对象

需要拆解不必要的嵌套,让类结构和JSON层级一一对应:

' 对应JSON根对象
Public Class OrderRoot
    Public recordSetTotal As Integer
    ' 用List更灵活,和JSON数组对应;数组写法两种都可以,见下文说明
    Public ordersList As List(Of OrderItem)
End Class

' 对应ordersList数组中的每个元素
Public Class OrderItem
    Public orderDetails As OrderDetail
    Public addressLine() As String
End Class

' 对应orderDetails对象
Public Class OrderDetail
    Public grandTotal As Single
    Public placedDate As String
End Class

2. 两种数组声明写法完全等价

你提到的两种数组声明方式:

Public ordersList() As ordersList

和

Public ordersList As ordersList()

在VB.NET中是完全等价的,仅语法写法不同,功能没有区别。不过更推荐使用List(Of T)泛型集合,它比数组更灵活(支持动态增删元素),Newtonsoft.Json对泛型集合的支持也更完善。

3. 修正后的反序列化代码

用调整后的类结构反序列化,就能直接得到完整的对象模型,性能远高于循环调用selectToken:

Dim orderRoot As OrderRoot = JsonConvert.DeserializeObject(Of OrderRoot)(orderData)
' 直接访问数据示例:获取第一个订单的总价
Dim firstTotal = orderRoot.ordersList(0).orderDetails.grandTotal

内容的提问来源于stack exchange,提问作者Dan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.30 13:02:34