I'm sending dates from my web app in UTC format, but when I recieve them on the server side, the JSon serializer (which is probably used by setting up your model) makes this in a local date & time with DateTimeKind.Local relative to the server's time zone.
When I do a DateTime.ToUniversalTime() I'm getting the proper UTC date, so this isn't a problem. Conversion works correctly and dates are sent the way they should... but.... I don't like to make a call to 'ToUniversalTime()' on every date on my model before I store it into a database... This is prone to errors and easy to forget when you have a big app.
So here's the question: Is there a way to tell MVC that incoming dates should always be expressed in UTC format?
After digging a bit more, I've found a way to make this work.
The problem wasn't so much the serializer, only the problem that the model's dates aren't expressed in UTC but in local time. ASP.Net allows you to create custom model binders and I think this is the key to change dates to UTC once they are deserialized.
I've used the following code to make this work, there might be a few bugs to iron out, but you will 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'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);
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With