【问题标题】:VB.NET Deserialize JSON - Cannot deserialize the current JSON object into type .Customer[]' because the type requires a JSON arrayVB.NET 反序列化 JSON - 无法将当前 JSON 对象反序列化为 .Customer[]' 类型,因为该类型需要 JSON 数组
【发布时间】:2019-03-18 12:18:53
【问题描述】:

我正在开发一个系统,它将向 VB.NET 中的 Web API 发送 POST 或 GET 请求。

我正在使用 Newtonsoft.Json 将返回的 JSON 字符串转换为 VB 对象。

尝试反序列化响应时出现以下错误。

无法将当前 JSON 对象(例如 {"name":"value"})反序列化为类型 'ProjectName.Customer[]',因为该类型需要 JSON 数组(例如 [1,2,3])才能正确反序列化. 要修复此错误,请将 JSON 更改为 JSON 数组(例如 [1,2,3])或更改反序列化类型,使其成为普通的 .NET 类型(例如,不是像整数这样的原始类型,而不是像这样的集合类型可以从 JSON 对象反序列化的数组或列表。 JsonObjectAttribute 也可以添加到类型中以强制它从 JSON 对象反序列化。 路径“customers.id”,第 1 行,位置 19。

API 返回给我的 JSON 字符串是:

{"customers":{"id":"CU0004FEY6D7HA","created_at":"2018-10-13T13:30:21.320Z","email":"test@test.com","given_name": "Joe","family_name":"Bloggs","company_name":null,"address_line1":"1 街道名称","address_line2":"","address_line3":null,"city":"伦敦"," region":null,"postal_code":"SW1A 1AA","country_code":"GB","language":"en","swedish_identity_number":null,"danish_identity_number":null,"phone_number":null,"metadata ":{}}}

我已经为对象创建了一个类。

VB.NET 不是我最擅长的,因为我主要使用 PHP。

谁能提供有用的建议?

Public Class CustomerWrapper
    Public customers() As Customer
End Class

Public Class Metadata
    Public Property id() As String
        Get
            Return m_id
        End Get
        Set(value As String)
            m_id = value
        End Set
    End Property
    Private m_id As String
End Class

Public Class Customer

    Public Property id() As String
        Get
            Return m_id
        End Get
        Set(value As String)
            m_id = value
        End Set
    End Property
    Private m_id As String
    Public Property created_at() As String
        Get
            Return m_created_at
        End Get
        Set(value As String)
            m_created_at = value
        End Set
    End Property
    Private m_created_at As String
    Public Property email() As String
        Get
            Return m_email
        End Get
        Set(value As String)
            m_email = value
        End Set
    End Property
    Private m_email As String
    Public Property given_name() As String
        Get
            Return m_given_name
        End Get
        Set(value As String)
            m_given_name = value
        End Set
    End Property
    Private m_given_name As String
    Public Property family_name() As String
        Get
            Return m_family_name
        End Get
        Set(value As String)
            m_family_name = value
        End Set
    End Property
    Private m_family_name As String
    Public Property address_line1() As String
        Get
            Return m_address_line1
        End Get
        Set(value As String)
            m_address_line1 = value
        End Set
    End Property
    Private m_address_line1 As String
    Public Property address_line2() As String
        Get
            Return m_address_line2
        End Get
        Set(value As String)
            m_address_line2 = value
        End Set
    End Property
    Private m_address_line2 As String
    Public Property address_line3() As String
        Get
            Return m_address_line3
        End Get
        Set(value As String)
            m_address_line3 = value
        End Set
    End Property
    Private m_address_line3 As String
    Public Property city() As String
        Get
            Return m_city
        End Get
        Set(value As String)
            m_city = value
        End Set
    End Property
    Private m_city As String
    Public Property region() As String
        Get
            Return m_region
        End Get
        Set(value As String)
            m_region = value
        End Set
    End Property
    Private m_region As String
    Public Property postal_code() As String
        Get
            Return m_postal_code
        End Get
        Set(value As String)
            m_postal_code = value
        End Set
    End Property
    Private m_postal_code As String
    Public Property country_code() As String
        Get
            Return m_country_code
        End Get
        Set(value As String)
            m_country_code = value
        End Set
    End Property
    Private m_country_code As String
    Public Property language() As String
        Get
            Return m_language
        End Get
        Set(value As String)
            m_language = value
        End Set
    End Property
    Private m_language As String
    Public Property phone_number() As String
        Get
            Return m_phone_number
        End Get
        Set(value As String)
            m_phone_number = value
        End Set
    End Property
    Private m_phone_number As String
    Public metadata() As Metadata
End Class

调用Json的代码是

Dim response = apiCall.CallApi()

        'Dim customerId = customers("id")

        Dim customerWrapper = JsonConvert.DeserializeObject(Of CustomerWrapper)(response)
        Dim customers = customerWrapper.customers

【问题讨论】:

  • Public Property customers() As Customer 中更改CustomerWrapper customers() 声明。您不需要那些支持字段。使用自动属性(例如,Public Property id() As StringPublic Property family_name() As String 等,仅此而已。)您还应该使用 JsonProperty 属性(例如,<JsonProperty("family_name")> Public Property FamilyName() As String)

标签: json vb.net json.net


【解决方案1】:

您收到此异常是因为您在类中的几个成员中省略了 Property 关键字,这会改变括号的语义。

例如,在您的CustomerWrapper 类中,您已像这样声明customers 成员:

Public customers() As Customer

由于声明没有Property关键字,这意味着customers是类中的一个字段,这里的括号表示它是一个数组。这其实和在数据类型后面用括号声明字段是一样的:

Public customers As Customer()   ' Field - array of Customer

相反,在属性声明中,名称后面的括号表示完全不同的含义:在这里,它们表示一个空参数列表。 (属性实际上是一种方法,所以它可以有参数,虽然大多数属性没有。如果属性没有任何参数,属性名后面的括号是可选的。)

Public Property customers() As Customer   ' Property - single Customer

因此,底线是您尝试将单个客户对象反序列化为声明为数组的 customers 字段,从而导致您看到的异常。

要修复,只需添加Property 关键字,如上所示。您还需要修复 Customer 类中的 metadata 字段;它有同样的问题。

作为一个仅供参考,您可以通过摆脱支持字段来大大简化您的代码。您的所有属性都没有任何逻辑,因此您可以省略实现并改用auto-implemented properties(基本上编译器会在幕后为您生成支持字段并获取/设置样板)。当您使用它时,我还会去掉属性名称上的可选括号。

通过这些更改,您的类将如下所示,IMO 更具可读性:

Public Class CustomerWrapper
    Public Property customers As Customer
End Class

Public Class Metadata
    Public Property id As String
End Class

Public Class Customer
    Public Property id As String
    Public Property created_at As String
    Public Property email As String
    Public Property given_name As String
    Public Property family_name As String
    Public Property address_line1 As String
    Public Property address_line2 As String
    Public Property address_line3 As String
    Public Property city As String
    Public Property region As String
    Public Property postal_code As String
    Public Property country_code As String
    Public Property language As String
    Public Property phone_number As String
    Public Property metadata As Metadata
End Class

小提琴:https://dotnetfiddle.net/vEnbnI

【讨论】:

    猜你喜欢
    • 2022-06-11
    • 1970-01-01
    • 2021-10-29
    • 2020-04-17
    • 1970-01-01
    • 2020-11-15
    • 2022-01-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多