2017-08-03 69 views
0

看過很多谷歌搜索和StackOverflow的帖子後,我已經得出結論,我可能需要創建我自己的轉換器。然而,這對我來說是非常非常新的,我不確定我會在這些帖子中看到哪些例子(如果有的話)。Json.NET(德)序列化郵件地址

我有這個類(實際類是比這更復雜)

public class Person { 
    [JsonProperty(PropertyName = "id")] 
    public string PersonId { get; set; } 

    [JsonProperty(PropertyName = "firstName")] 
    public string PersonFirstName { get; set; } 

    [JsonProperty(PropertyName = "email")] 
    public MailAddress PersonEmail { get; set; } 
} 

我需要序列化和反序列化下面的JSON

{ 
    "id" : "abc123" 
    , "firstName" : "John" 
    , "email" : "[email protected]" 
} 

如何反序列化包含MailAddress到stringMailAddress.Address,反之亦然。

我得到的錯誤是:

無法施放或從System.String轉換爲 System.Net.Mail.MailAddress

+2

你有什麼問題? Json.NET應該閉着眼睛做這件事。 – CodingYoshi

+1

@CodingYoshi,你可以在這裏看到https://dotnetfiddle.net/XbUVci它不起作用。 – kiziu

+0

@kiziu謝謝。你太快=) – RoLYroLLs

回答

4

Json.NET不與一些發揮出色.Net類型,如System.Net.IPAddressSystem.Net.Mail.MailAddress。除非你願意修改您的JSON,那麼你就必須按順序使用它們(從here採取代碼)編寫自定義轉換器:

public class MailAddressConverter : JsonConverter 
{ 
    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) 
    { 
     var mailAddress = value as MailAddress; 
     writer.WriteValue(mailAddress == null? string.Empty : mailAddress.ToString()); 
    } 

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) 
    { 
     var text = reader.Value as string; 
     MailAddress mailAddress; 

     return IsValidMailAddress(text, out mailAddress) ? mailAddress : null; 
    } 

    public override bool CanConvert(Type objectType) 
    { 
     return objectType == typeof(MailAddress); 
    } 

    private static bool IsValidMailAddress(string text, out MailAddress value) 
    { 
     try 
     { 
      value = new MailAddress(text); 
      return true; 
     } 
     catch 
     { 
      value = null; 
      return false; 
     } 
    } 
} 

然後,你可以修改你的類作爲作者的那個帖子提示:

public class Person 
{ 
    [JsonProperty(PropertyName = "id")] 
    public string PersonId { get; set; } 

    [JsonProperty(PropertyName = "firstName")] 
    public string PersonFirstName { get; set; } 

    [JsonConverter(typeof(MailAddressConverter))] 
    [JsonProperty(PropertyName = "email")] 
    public MailAddress PersonEmail { get; set; } 
} 

... ,你可以使用我的首選方法,這就是使用Json.NET的JsonSerializerSettings

public sealed class SerializerSettings : JsonSerializerSettings 
{ 
    public SerializerSettings() : base() 
    { 
     this.Converters.Add(new MailAddressConverter()); 
    } 
} 

然後在您的Main()

JsonConvert.DefaultSettings =() => new SerializerSettings(); 
+0

謝謝!也許我會在谷歌搜索吸引人的,即使這些年過去了。你知道我正在搜索'C#Newtonsoft.Json MailAddress',這篇文章沒有顯示出來,但是把它改成了'C#Json.Net MailAddress',它是第四行。這看起來不錯。我會試試看。 – RoLYroLLs

+0

我認爲'JsonConverter'的標準方法不是檢查提供的值是否對給定的類型有效,只要讓構造函數/解析器將其排除並在未能這樣做時拋出異常。看看這裏 - https://github.com/JamesNK/Newtonsoft.Json/blob/master/Src/Newtonsoft.Json/Converters/IsoDateTimeConverter.cs,它不捕捉任何東西,只是運行解析。 – kiziu

+0

@RoLYroLLs在過去處理過這類問題(對於IPAddress和IPEndpoint對象),我立即發現了錯誤,只需要搜索'C#newtonsoft MailAddress converter'。 – stybl

1

您的JSON結構需要是這樣的,因爲MailAddress是一個對象:

{ 
    "id": "1", 
    "firstName": "George", 
    "email": { 
     "DisplayName": "", 
     "User": "test", 
     "Host": "test.com", 
     "Address": "[email protected]" 
    } 
} 

你可以做一個簡單的測試是這樣看所產生的JSON :

var person = new Person 
{ 
    PersonEmail = new System.Net.Mail.MailAddress("[email protected]"), 
    PersonFirstName = "George", 
    PersonId = "1" 
}; 

var serialized = JsonConvert.SerializeObject(person); 
+0

謝謝,但我無法更改Json,因爲它是第三方數據。確切地使用Salesforce API。 – RoLYroLLs