由于Web API快速迭代了好几个版本,在最新版本的格式化中,对于时间的格式化设置,记录一下。

    Web API 3.0中的Json序列化,使用的是System.Text.Json这个序列化类。在不对其进行设置的情况下,对于日期格式,输出的内容形式是:

2020-06-30T06:16:38.62
   默认使用System.Text.Json时的解决办法

在日期和时间中间有字母"T",这是一种IsoDateTime格式,有些时候,我们需要自定义格式,比如把中间的T去掉,以方便客户端使用。那么怎么办呢?那么就需要自定义数据类型转换。

public void ConfigureServices(IServiceCollection services)
{
    services.AddControllers().AddJsonOptions(o =>
    {
        o.JsonSerializerOptions.Converters.Add(new DateTimeConverter());
    });
    ........
}

 通过AddJsonOptions扩展方法,里面的JsonSerializerOptions里的Converters来自定义时间转换,这里自定义的类需要继承JsonConverter<T>泛型类:

public class DateTimeConverter : JsonConverter<DateTime>
{
    public override DateTime Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
    {
        Debug.Assert(typeToConvert == typeof(DateTime));
        return DateTime.Parse(reader.GetString());
    }

    public override void Write(Utf8JsonWriter writer, DateTime value, JsonSerializerOptions options)
    {
        writer.WriteStringValue(value.ToUniversalTime().ToString("yyyy'-'MM'-'dd' 'HH':'mm':'ss"));
    }
}

这里面定义了Read和Write方法,在序列化的时候用Write方法,反序列化的时候,用Read方法。因为是WebApi的返回Json,所以这里的Write方法里,制定了“yyyy-MM-dd HH:mm:ss”,需要注意的是,这里的分隔符需要用单引号引起来。这样,对于日期类型,就可以正确显示为如下格式了:

2020-06-29 22:16:38

需要注意的是,在没有自定义前,输出的其实是Ios的格式不包含时区,这也是博客的日期存储方式,在展示的时候,根据当地时区来转换,所以这里减了8个小时,在实际中我们应该在转换时去掉这种时区,返回UTC时间,让客户端处理。

JsonSerializerOptions中,还有一些属性,可以控制格式化时的行为,在需要用到的时候,可以关注一下。

上述是使用的自带的Json序列化类库,这个库功能方面没有常用的Newtonsoft.Json强大,微软也提供了如何从Newtonsoft.Json到System.Text.Json的建议

使用Newtonsoft.Json的解决方法

要在Web API 3.0中使用Newtonsoft.Json作为Json的格式化器,首先需要安装Microsoft.AspNetCore.Mvc.NewtonsoftJson包。安装完成之后,使用AddNewtonsoftJson扩展方法即可,并在其中设置格式化格式即可:

public void ConfigureServices(IServiceCollection services)
{
    services.AddControllers().AddNewtonsoftJson(option =>
      {
          option.SerializerSettings.DateFormatString = "yyyy'-'MM'-'dd' 'HH':'mm':'ss";
      });
    ...
}

或:

public void ConfigureServices(IServiceCollection services)
{
    services.AddControllers().AddNewtonsoftJson(o =>
    {
        o.SerializerSettings.Converters.Add(new IsoDateTimeConverter { DateTimeFormat = "yyyy'-'MM'-'dd' 'HH':'mm':'ss" });
    });
    ...
}

这里的格式化字符串,连接符也要使用单引号引起来。跟上面的类似。

Newtonsoft.Json,默认如果设置日期格式化方式的话,跟System.Text.Json默认情况下对DataTime的格式化处理行为是一致的,都是输出IsoDateTime。如果要输出Javascript类型的日期格式,那么只需要在Converters里增内置的JavaScriptDateTimeConverter类型即可:

public void ConfigureServices(IServiceCollection services)
{
    services.AddControllers().AddNewtonsoftJson(option =>
    {
        //option.SerializerSettings.Converters.Add(new IsoDateTimeConverter());
        option.SerializerSettings.Converters.Add(new JavaScriptDateTimeConverter());
    });
}

这样,输出的日期格式即为:

new Date(1593468998620)

 在Javascript里可以直接使用。