vb.NET 将 JSON 列表反序列化为对象

vb.NET Deserialise JSON list into object

我还没有完全找到我正在寻找的确切答案,所以我想我会问这个问题。

我目前正在尝试使用 Json.NET 将 JSON 字符串反序列化为 vb.NET 中的对象;我之前通过设置适当的 Classes 然后使用 Parent Class 将字符串反序列化为一个对象来完成一些工作并且它们工作正常但是这个似乎并没有崩溃很对。

我试图分解的字符串示例如下:

   [
    {
        "value": 12345,
        "text": "Example Unique Text"
    },
    {
        "InnerList": [
            {
                "value": 4746,
                "text": "A duplicated entry of text"
            },
            {
                "value": 4747,
                "text": "A duplicated entry of text"
            },
            {
                "value": 4748,
                "text": "A duplicated entry of text"
            },
            {
                "value": 4749,
                "text": "A duplicated entry of text"
            },
            {
                "value": 4750,
                "text": "A duplicated entry of text"
            },
            {
                "value": 4751,
                "text": "A duplicated entry of text"
            },
            {
                "value": 4752,
                "text": "A duplicated entry of text"
            },
            {
                "value": 4753,
                "text": "A duplicated entry of text"
            },
            {
                "value": 4754,
                "text": "A duplicated entry of text"
            },
            {
                "value": 4755,
                "text": "A duplicated entry of text"
            }
        ],
        "duplicated": "Yes"
    },
    {
        "value": 15298,
        "text": "Another Example Unique Text"
    },
    {
        "value": 959,
        "text": "Yet more uniqueness"
    },
    {
        "value": 801,
        "text": "A final little bit of unique text"
    }
]

我试过通过一些外部工具传递它,它们都返回相同的 Class 定义,但它们似乎没有用。因此,根据我对 JSON 的理解,我整理了以下内容:

 Public Class ItemDetails

        Public Value As Integer
        Public Text As String

 End Class

 Public Class ItemArray

        Public DetailList As List(Of ItemDetails)
        Public Duplicated As String

 End Class

 Public Class GeneralArray

        Public GeneralList As List(Of ItemArray)

 End Class

GeneralArray 是父级 Class,用于解析 JSON。

然后我尝试将字符串反序列化为父 Class。在下面的示例中,是上面概述的 JSON 字符串,而 JSONStringCollection 是定义了 GeneralArray 的模块:

Dim JSONString As String

JSONString = "<JSONStringDetails>"

Dim JSONObj = JsonConvert.DeserializeObject(Of JSONStringCollection.GeneralArray)(JSONString)

可悲的是,当通过这个时,返回以下内容并且例程中断:

An unhandled exception of type 'Newtonsoft.Json.JsonSerializationException' occurred in Newtonsoft.Json.dll

Additional information: Cannot deserialize the current JSON array (e.g. [1,2,3]) into type 'ShadOS.JSONStringCollection+GeneralArray' because the type requires a JSON object (e.g. {"name":"value"}) to deserialize correctly.

我错过了什么?

您的 JSON 字符串表示对象的 数组 (您可以看到这一点,因为所有内容都包含在 [] 之间)。

错误信息是"you tried to deserialize an array of objects into a single object"。您的目标类型 GeneralArray 的行为不像数组(例如,它既不继承自 array/collection 类型,也不实现集合接口)。

另一个问题是,JSON 数组是 "mixed" - 它包含一些看起来像 ItemDetails 的对象和其他看起来像 ItemArray 的对象。在像 VB.NET 这样的静态语言中,这更难反序列化为不同类型的单个集合。

一个可能的解决方案是将您的目标 classes ItemDetailsItemArray 合并为一个 class,按照

Public Class CombinedItem
    'properties from ItemDetails
    Public Value As Integer
    Public Text As String

    'properties from ItemArray
    Public InnerList As List(Of CombinedItem)
    Public Duplicated As String

End Class

鉴于此 class,您的反序列化可能如下所示:

Dim JSONObj = JsonConvert.DeserializeObject(Of List(Of CombinedItem))(JSONString)

这里的关键是你告诉 Newtonsoft 目标类型是一个 List(Of CombinedItem) - 一个像 array/collection 的目标。

现在 JSONObjCombinedItem 的集合 - 有些会有 Value/Text 属性,其他会有 InnerList/Duplicated 属性.