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

Jer*_*eer 8 c# ajax asp.net-mvc json

我以UTC格式从我的网络应用程序发送日期,但是当我在服务器端接收它们时,JSon序列化程序(可能通过设置模型使用)使用DateTimeKind.Local相对于本地日期和时间到服务器的时区.

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

所以这里有一个问题:有没有办法告诉MVC传入日期应该始终以UTC格式表示?

Jer*_*eer 3

经过更多挖掘后,我找到了一种方法来完成这项工作。

问题不在于序列化器,而在于模型的日期不是以 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);

  }
}
Run Code Online (Sandbox Code Playgroud)