自1970年以来,如何使Web API将任何对象的DateTime序列化为毫秒数?

时间:2017-07-06 18:31:49

标签: c# asp.net-web-api json.net

在我的ASP.NET Web服务中,我需要将所有日期序列化为JSON作为数字,表示自1970年以来经过的毫秒数。我正在使用Newtonsoft.Json序列化程序。我需要做什么才能以这种方式进行设置?

更新: 可用文档(http://www.newtonsoft.com/json/help/html/DatesInJSON.htm)仅提及使用自定义设置序列化单个对象,我要查找的是控制任何对象序列化的默认序列化设置

4 个答案:

答案 0 :(得分:0)

离开我的头顶我会得到1970年日期的刻度从当前日期的刻度中减去它然后除以10000,因为在一个毫秒内有10000个刻度。这将为您提供一个应该更容易序列化的数字。你可以使这成为DateTime的扩展方法。 MSDN上的蜱虫: DateTime.Ticks

答案 1 :(得分:0)

查看this excellent blog post创建自己的DateTime转换器以处理您的需求。示例实际上显示了您创建UnixDateTimeConverter。

答案 2 :(得分:0)

我不确定这是否是最简单的方法,但您可以为DateTimes创建自定义转换器,然后使用该转换器创建自定义JsonMediaTypeFormatter。

// This class overrides conversion for DateTime values
public class MyDateConverter : JsonConverter
{
    public override bool CanConvert(Type objectType)
    {
        return objectType == typeof(DateTime);
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        // Your algorithm here
        var customValue = ((DateTime)value).Ticks;
        writer.WriteValue(customValue);
    }
}

// This formatter will create serializers with the above converter injected
public class MyJsonFormatter : JsonMediaTypeFormatter
{
    public override JsonSerializer CreateJsonSerializer()
    {
        var serializer = base.CreateJsonSerializer();
        serializer.Converters.Add(new MyDateConverter());
        return serializer;
    }
}

// Inside your WebApi config code, replace the default formatter with your custom one
var defaultJsonFormatter = config.Formatters.OfType<JsonMediaTypeFormatter>().First();
config.Formatters.Remove(defaultJsonFormatter);
config.Formatters.Insert(0, new MyJsonFormatter());

答案 3 :(得分:0)

这是有效的:

public class MyConverter: JsonConverter
{
    public override bool CanConvert(Type type)
    {
        return (type == typeof(DateTime) || type == typeof(DateTime?));
    }
    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        return new NotSupportedException("An attempt to read a date using a write-only converter from DateTime -> number of milliseconds since 1970.");
    }

    static readonly long ticksTo1970 = new DateTime(1970, 1, 1).Ticks;

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        if (value is DateTime)
        {
            var date = (DateTime)value;
            var unixDateSpan = new TimeSpan(date.Ticks - ticksTo1970);
            var milliseconds = (long)unixDateSpan.TotalMilliseconds;
            writer.WriteValue(milliseconds);
        }
        else
        {
            throw new NotSupportedException("A value of unexpected type where a DateTime value is expected.");
        }
    }
}

public class BaseApiController : ApiController
{
    [NonAction]
    protected JsonResult<T> MyJson<T>(T data)
    {
        var result = this.Json(data);
        result.SerializerSettings.Converters.Insert(0, new MyConverter());
        return result;
    }   
}