如何告诉ASP.NETMVC从JSon反序列化的所有传入日期都应该是UTC

本文关键字:日期 UTC NETMVC ASP 何告诉 JSon 反序列化 | 更新日期: 2023-09-27 18:26:24

我从我的web应用程序以UTC格式发送日期,但当我在服务器端收到它们时,JSon序列化程序(可能用于设置您的模型)会在本地日期&DateTimeKind.Local相对于服务器时区的时间。

当我做DateTime.ToUniversalTime()时,我得到了正确的UTC日期,所以这不是问题。转换工作正常,日期以应有的方式发送。。。但是我不喜欢在模型的每个日期都调用"ToUniversalTime()",然后再将其存储到数据库中当你有一个大应用程序时,这很容易出错,很容易忘记。

所以问题来了:有没有办法告诉MVC,传入日期应该总是用UTC格式表示?

如何告诉ASP.NETMVC从JSon反序列化的所有传入日期都应该是UTC

经过更多的挖掘,我找到了一种方法来实现这一点。

问题不在于序列化程序,而在于模型的日期不是用UTC表示,而是用当地时间表示。ASP.Net允许您创建自定义模型绑定,我认为这是将日期反序列化后更改为UTC的关键。

我使用了以下代码来实现这一点,可能有一些错误需要解决,但你会明白的:

public class UtcModelBinder : DefaultModelBinder
{
  protected override void SetProperty(ControllerContext controllerContext, ModelBindingContext bindingContext, System.ComponentModel.PropertyDescriptor propertyDescriptor, object value)
  {
    HttpRequestBase request = controllerContext.HttpContext.Request;
    // Detect if this is a JSON request
    if (request.IsAjaxRequest() &&
      request.ContentType.StartsWith("application/json", StringComparison.OrdinalIgnoreCase))
    {
      // See if the value is a DateTime
      if (value is DateTime)
      {
        // This is double casting, but since it's a value type there's not much other things we can do
        DateTime dateValue = (DateTime)value;
        if (dateValue.Kind == DateTimeKind.Local)
        {
          // Change it
          DateTime utcDate = dateValue.ToUniversalTime();
          if (!propertyDescriptor.IsReadOnly && propertyDescriptor.PropertyType == typeof(DateTime))
            propertyDescriptor.SetValue(bindingContext.Model, utcDate);
          return;
        }
      }
    }
    // Fall back to the default behavior
    base.SetProperty(controllerContext, bindingContext, propertyDescriptor, value);
  }
}