简体   繁体   中英

Json.NET (De)serialize MailAddress

After looking at many Google searches and StackOverflow posts I've com to the conclusion I may nee to create my own converter. However, this is very, very new to me and I'm not sure which, if any, of the examples I see in these posts am I to use.

I have this class (actual class is more complex than this)

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; }
}

I need to serialize and deserialize the following json

{
    "id" : "abc123"
    , "firstName" : "John"
    , "email" : "john@doe.com"
}

How do I deserialize the MailAddress to a string containing MailAddress.Address and vice-versa.

The error I get is:

Could not cast or convert from System.String to System.Net.Mail.MailAddress

Json.NET doesn't play well with some .Net types like System.Net.IPAddress or System.Net.Mail.MailAddress . Unless you're willing to modify your JSON, then you'll have to write a custom converter in order to use them (code taken from 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;
        }
    }
}

Then, you can either modify your class as the author of that post suggests:

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; }
}

.. or , you can use my preferred approach, which is to use Json.NET's JsonSerializerSettings :

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

Then in your Main() :

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

Your json structure needs to be like this because MailAddress is an object:

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

You can do a quick test like this to see the JSON that is produced:

var person = new Person
{
    PersonEmail = new System.Net.Mail.MailAddress("test@test.com"),
    PersonFirstName = "George",
    PersonId = "1"
};

var serialized = JsonConvert.SerializeObject(person);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM