.NET Web API如何仅对入参应用IsoDateTimeConverter并自定义出参日期格式
解决方案:分离Web API入参和出参的日期序列化规则
要实现入参用yyyy-MM-ddTHH:mm:ss.fffZ格式解析,出参用yyyy-MM-dd HH:mm:ss格式输出,核心是要将入参与出参的JSON序列化配置分开——全局统一配置会同时影响双方,而ActionFilter的执行时机太晚(模型绑定已完成),无法干预入参的日期解析过程。
针对.NET Framework(使用Newtonsoft.Json)
1. 自定义入参JSON格式化器
创建专用的输入格式化器,仅用于处理请求参数的日期解析:
public class CustomJsonInputFormatter : JsonMediaTypeFormatter { public CustomJsonInputFormatter() { var inputSettings = new JsonSerializerSettings(); // 配置入参的日期解析规则,指定UTC格式并强制转换为UTC时间避免时差 inputSettings.Converters.Add(new IsoDateTimeConverter() { DateTimeFormat = "yyyy-MM-ddTHH:mm:ss.fffZ", DateTimeStyles = DateTimeStyles.AdjustToUniversal }); this.SerializerSettings = inputSettings; } }
2. 在WebApiConfig中配置分离规则
替换默认的JSON格式化器,分别指定入参和出参的规则:
public static void Register(HttpConfiguration config) { // 移除默认的JSON输入格式化器 config.Formatters.Remove(config.Formatters.JsonFormatter); // 添加自定义输入格式化器(处理入参日期解析) config.Formatters.Add(new CustomJsonInputFormatter()); // 配置出参的JSON格式化器,设置目标日期格式 var outputSettings = new JsonSerializerSettings(); outputSettings.Converters.Add(new IsoDateTimeConverter() { DateTimeFormat = "yyyy-MM-dd HH:mm:ss" }); config.Formatters.JsonFormatter.SerializerSettings = outputSettings; }
针对ASP.NET Core(使用Newtonsoft.Json)
在Program.cs中直接配置分离规则:
var builder = WebApplication.CreateBuilder(args); builder.Services.AddControllers() .AddNewtonsoftJson(options => { // 配置出参的日期输出格式 options.SerializerSettings.Converters.Add(new IsoDateTimeConverter() { DateTimeFormat = "yyyy-MM-dd HH:mm:ss" }); }) .AddMvcOptions(options => { // 替换默认的JSON输入格式化器,使用自定义规则处理入参 options.InputFormatters.RemoveType<NewtonsoftJsonInputFormatter>(); options.InputFormatters.Add(new NewtonsoftJsonInputFormatter( options, new JsonSerializerSettings { Converters = { new IsoDateTimeConverter() { DateTimeFormat = "yyyy-MM-ddTHH:mm:ss.fffZ", DateTimeStyles = DateTimeStyles.AdjustToUniversal }} })); }); var app = builder.Build(); // 其他中间件配置... app.MapControllers(); app.Run();
为什么之前的ActionFilter方案无效?
OnActionExecuting方法的执行时机是模型绑定完成之后,此时请求中的日期字符串已经被默认序列化器转换为DateTime对象,修改配置无法回溯到解析阶段;同时时区偏差是因为默认解析器未处理Z后缀(UTC标识),导致按本地时区解析,最终出现时差。
内容的提问来源于stack exchange,提问作者Silva
相关产品推荐
相关产品推荐

