如何在Web API中配置JSON序列化器区分输入输出日期转换器
解决Web API输入/输出日期转换器分离配置的问题
这个场景太常见了——默认的Json转换器会把同一个配置同时应用到**反序列化(输入参数解析)和序列化(输出结果生成)**上,要实现「输入转UTC、输出用ISO 8601」的需求,你可以试试下面两种方案:
方案一:分别配置读写序列化设置
ASP.NET Web API的JsonMediaTypeFormatter提供了分开的ReadSerializerSettings和WriteSerializerSettings属性,刚好可以分别控制输入和输出的行为:
// 获取全局Json格式化器 var jsonFormatter = config.Formatters.JsonFormatter; // 配置输入参数:将日期转换为UTC格式 var inputConverter = new IsoDateTimeConverter { DateTimeStyles = DateTimeStyles.AdjustToUniversal }; jsonFormatter.ReadSerializerSettings.Converters.Add(inputConverter); // 配置输出结果:使用标准ISO 8601格式 var outputConverter = new IsoDateTimeConverter { // 这里的格式字符串会生成带时区信息的ISO 8601格式,比如 2024-05-20T12:34:56.789Z DateTimeFormat = "yyyy'-'MM'-'dd'T'HH':'mm':'ss.fffK" }; jsonFormatter.WriteSerializerSettings.Converters.Add(outputConverter);
这种方式的好处是逻辑清晰,完全分开控制输入和输出的转换规则,不需要自定义转换器。
方案二:自定义区分读写的DateTime转换器
如果你希望用一个转换器搞定所有逻辑,可以继承IsoDateTimeConverter,重写读写方法来分别处理:
public class UtcInputIsoOutputDateTimeConverter : IsoDateTimeConverter { public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { // 处理输入时,强制将日期转换为UTC this.DateTimeStyles = DateTimeStyles.AdjustToUniversal; return base.ReadJson(reader, objectType, existingValue, serializer); } public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) { // 处理输出时,使用标准ISO 8601格式 this.DateTimeFormat = "yyyy'-'MM'-'dd'T'HH':'mm':'ss.fffK"; this.DateTimeStyles = DateTimeStyles.None; base.WriteJson(writer, value, serializer); } }
然后只需要注册这个自定义转换器即可:
config.Formatters.JsonFormatter.SerializerSettings.Converters.Add(new UtcInputIsoOutputDateTimeConverter());
补充说明
- 如果你用的是ASP.NET Core,配置逻辑类似,只是需要在
Startup.cs或Program.cs中通过AddJsonOptions来配置读写设置。 - 标准ISO 8601格式默认就包含时区信息,如果你不需要时区,也可以把输出的格式字符串改成
"yyyy'-'MM'-'dd'T'HH':'mm':'ss.fff"。
内容的提问来源于stack exchange,提问作者Simple Code
相关产品推荐
相关产品推荐

