基于属性的DateTimeOffset自定义序列化/反序列化

时间:2014-08-06 12:30:28

标签: json.net

如果使用属性标记属性,是否可以将JSON.NET配置为以不同方式序列化/反序列化?

public class Person {
    [DateOnly]
    public DateTimeOffset Birthday {get;set;}
}

public class Meeting {
    public DateTimeOffset Date {get;set;}
}

人应序列化为

{"Birthday": {"year": 1980, "month": 2, "day": 1}}

会议应序列化为

{"Date": "2012-12-31T21:03:54.735168+00:00"}

1 个答案:

答案 0 :(得分:3)

您可以通过编写自定义JsonConverter并使用它来装饰Birthday类的Person属性来实现此目的。像这样:

public class DateTimeOffsetConverter : JsonConverter
{

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        var val = (DateTimeOffset)value;

        writer.WriteStartObject();
        writer.WritePropertyName("year");
        writer.WriteValue(val.Year);
        writer.WritePropertyName("month");
        writer.WriteValue(val.Month);
        writer.WritePropertyName("day");
        writer.WriteValue(val.Day);
        writer.WriteEndObject();
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        var jObject = JObject.Load(reader);

        var year = int.Parse(jObject["year"].ToString());
        var month = int.Parse(jObject["month"].ToString());
        var day = int.Parse(jObject["day"].ToString());

        existingValue = new DateTimeOffset(new DateTime(year, month, day));

        return existingValue;
    }

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

您的Person课程应如下所示:

public class Person
{
    [JsonConverter(typeof(DateTimeOffsetConverter))]
    public DateTimeOffset Birthday { get; set; }
}

并且不应更改Meeting类。通过使用以下行来转换PersonMeeting类型的对象,您将获得所需的输出:

var p = new Person
{
    Birthday = DateTimeOffset.Now
};

var m = new Meeting
{
    Date = DateTimeOffset.Now
};

var personString = JsonConvert.SerializeObject(p);
var meetingString = JsonConvert.SerializeObject(m);

要从Person反序列化personString对象,您可以使用以下行:

var person = JsonConvert.DeserializeObject<Person>(personString);
相关问题