VB.NET反序列化JSON-无法将当前JSON对象反序列化为类型.Customer []',因为该类型需要JSON数组

时间:2018-10-13 13:40:43

标签: json vb.net json.net

我正在使用一个将POST或GET请求发送到VB.NET中的Web API的系统。

我正在使用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字符串是:

  

{“客户”:{“ id”:“ CU0004FEY6D7HA”,“ created_at”:“ 2018-10-13T13:30:21.320Z”,“电子邮件”:“ test@test.com”,“ given_name”: “ Joe”,“ family_name”:“ Bloggs”,“ company_name”:null,“ address_line1”:“ 1街道名称”,“ address_line2”:“”,“ address_line3”:null,“ city”:“伦敦”,“地区”:null,“邮政编码”:“ SW1A 1AA”,“国家/地区代码”:“ GB”,“语言”:“ en”,“ swedish_identity_number”:null,“ danish_identity_number”:null,“ phone_number”:null,“ metadata” “:{}}}

我为对象创建了一个类。

由于我主要使用PHP,因此VB.NET并不是我最强的技能。

任何人都可以提供有用的建议吗?

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

1 个答案:

答案 0 :(得分:1)

之所以会出现此异常,是因为您从类中的几个成员中省略了Property关键字,这会更改括号的语义。

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

Public customers() As Customer

由于声明中没有Property关键字,因此这意味着customers是该类中的 field ,此处的括号表示它是一个数组。这实际上与在数据类型后用括号声明该字段相同:

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

相反,在属性声明中,名称后的括号表示完全不同的内容:此处,它们表示空的参数列表。 (属性实际上是一种方法,因此它可以具有参数,尽管大多数属性没有。如果没有任何参数,则属性名称后面的括号是可选的。)

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

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

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

作为一个FYI,您可以通过摆脱支持字段来大大简化代码。您的属性都没有逻辑,因此您可以省略实现,而使用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