How to tell ASP.Net MVC that all incoming dates deserialized from JSon must be UTC?

I send dates from my web application in UTC, but when I get them on the server side, the JSon serializer (which is probably used when setting up your model) does this in the local date and time using DateTimeKind.Local relative to the server time zone .

When I do DateTime.ToUniversalTime (), I get the correct UTC date, so this is not a problem. The conversion works correctly, and the dates are sent as they should ... but .... I do not like to call "ToUniversalTime ()" on every date of my model before I store it in the database ... This is subject mistakes and is easily forgotten when you have a great application.

So here's the question: is there a way to tell MVC that incoming dates should always be expressed in UTC?

+8
json c # ajax asp.net-mvc
source share
1 answer

After digging a little more, I found a way to make this work.

The problem was not so much in the serializer as in the fact that the model dates are not expressed in UTC, but in local time. ASP.Net allows you to create custom model bindings, and I think this is the key to changing dates in UTC after they are deserialized.

I used the following code to make this work, there may be a few errors to smooth out, but you get the idea:

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 a value type there 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); } } 
+2
source share

All Articles