我有一个对象,其中包含一个名为Email的属性,其类型为System.Net.Mail.MailAddress
。我能够使用JSON.Net
序列化我的对象并将其存储在数据库中。但是,我无法成功反序列化我的对象。我得到的错误信息是:
无法找到用于类型
System.Net.Mail.MailAddress
的构造函数。一个类应该有一个默认的构造函数,一个带参数的构造函数或一个用JsonConstructor属性标记的构造函数。路径'Item1.Email.DisplayName'。
我知道MailAddress没有默认构造函数,这就是我收到此错误的原因。我的问题是,如果没有转换属性类型,有没有办法解决这个问题?我看到有自定义转换器,但我没有运气让JSON.Net成功反序列化这个属性。
更新
让我详细说明对象的外观和我尝试过的内容。该对象看起来像这样:
{
"Item1": {
"ReceiveNewsletter": false,
"HomePhone": "074567 8901",
"SpouseTitle": null,
"SpouseFirstName": null,
"SpouseLastName": null,
"Address": {
"StreetAddress1": "123 Fake Street",
"StreetAddress2": null,
"City": null,
"State": "QLD",
"PostalCode": "4627",
"Suburb": "Abercorn",
"AustralianAddress": true
},
"CustomerAddresses": [],
"ID": -1,
"Title": "",
"FirstName": "James",
"LastName": "Dean",
"DisplayName": "James Dean",
"Email": {
"DisplayName": "",
"User": "jamesdean890",
"Host": "fake.com.au",
"Address": "jamesdean890@fake.com.au"
},
"WorkPhone": null,
"OtherPhone": "",
"CellPhone": "0423 456 789",
"Notes": null
},
"Item2": {
"ID": -1,
"CustomerID": -1,
"Pet": {
"ID": -1,
"Name": "Fae",
"Breed": "Puppy Dog",
"DateOfDeath": "2013-08-28T00:00:00-05:00",
"ServiceDate": "2013-08-28T00:00:00-05:00",
"ContactDate": "0001-01-01T00:00:00-06:00",
"PetGender": 1,
"ReferralClinicID": 462,
"ReferralPaidDate": null,
"Row": "\u0000",
"Plot": -1,
"CollectedBy": null,
"DeliverDate": "0001-01-01T00:00:00-06:00",
"DeliveredBy": null,
"Customer": null,
"RenewDate": null
},
"Service": {
"ID": -1,
"Quantity": 1,
"Price": 285.0,
"ProductName": "Cremation",
"ProductID": 1,
"LineItemState": 0,
"Plaque": null,
"IsPlaque": false,
"Void": false
},
"LineItems": [],
"Notes": "",
"EnteredBy": null,
"IsRenewal": false,
"IsLocked": false,
"CreateDate": "0001-01-01T00:00:00-06:00",
"OrderTotal": 285.0
}
}
在我的联系课上,我有类似的东西:
<JsonConverter(GetType(EmailConverter))>
Public Property Email() As Net.Mail.MailAddress
Get
Return _Email
End Get
Set(ByVal value As Net.Mail.MailAddress)
_Email = value
End Set
End Property
然后我找到了一个像这样的转换器:
Public Class EmailConverter
Inherits JsonConverter
Public Overrides Function ReadJson(reader As JsonReader, objectType As Type, existingValue As Object, serializer As JsonSerializer) As Object
Dim mailAddress As System.Net.Mail.MailAddress = Nothing
If objectType = GetType(System.Net.Mail.MailAddress) Then
While reader.Path <> "Item1.Email.Address"
reader.Read()
End While
reader.Read()
mailAddress = New Net.Mail.MailAddress(reader.Value.ToString)
End If
Return mailAddress
End Function
Public Overrides Function CanConvert(objectType As Type) As Boolean
Return objectType = GetType(System.Net.Mail.MailAddress)
End Function
Public Overrides Sub WriteJson(writer As JsonWriter, value As Object, serializer As JsonSerializer)
End Sub
End Class
通过使用属性并将转换器添加到序列化程序,一旦序列化程序点击Email属性,它就会正确创建一个邮件对象,但之后的任何属性都不能正确反序列化。
答案 0 :(得分:0)
我认为问题是你的ReadJson
方法在读者完成时会使读者错误定位,从而弄乱了反序列化过程的其余部分。
将读者视为JSON数据的仅向前游标。调用ReadJson时,它的位置使得它即将读取转换器说它可以处理的下一个项目。对于EmailConverter
,它的位置即将阅读JSON的这一部分:
{
"DisplayName": "",
"User": "jamesdean890",
"Host": "fake.com.au",
"Address": "jamesdean890@fake.com.au"
}
由于转换器应该处理整个Email
对象,因此需要使用 all 该对象的JSON。我认为正在发生的事情是读者没有进入最后阶段。您可以通过在提取Address
值之后继续阅读更多来修复它,注意不要超出Email
对象的末尾,但这种方法容易出错。更好的想法是使用JSON.Net的内置LINQ-to-JSON工具,允许您轻松地将整个Email
对象作为块读取,然后从中挑选出您需要的部分。这将使读者正确地定位其余的反序列化,然后您不必担心它。它还大大简化了代码。
以下是我写EmailConverter
:
Imports System.Net.Mail
Imports Newtonsoft.Json
Imports Newtonsoft.Json.Linq
Public Class EmailConverter
Inherits JsonConverter
Public Overrides Function CanConvert(objectType As Type) As Boolean
Return objectType = GetType(MailAddress)
End Function
Public Overrides Function ReadJson(reader As JsonReader, objectType As Type, existingValue As Object, serializer As JsonSerializer) As Object
Dim jsonObject As JObject = JObject.Load(reader)
Dim address As String = jsonObject("Address").Value(Of String)()
Dim mailAddress As MailAddress = New MailAddress(address)
Return mailAddress
End Function
Public Overrides Sub WriteJson(writer As JsonWriter, value As Object, serializer As JsonSerializer)
serializer.Serialize(writer, value)
End Sub
End Class