tshao tshao - 1 year ago 136
JSON Question

Pass a JSON format DateTime to ASP.NET MVC

We know that MVC returns DateTime for JsonResult in this format:

/Date(1240718400000)/
, and we know how to parse it in JS.

However, It seems that MVC doesn't accept DateTime parameter being sent in this way. For example, I have the following Action.

[HttpGet]
public ViewResult Detail(BookDetail details) { //... }


The BookDetail class contains a DateTime field named CreateDate, and I passed a JSON object from JS in this format:

{"CreateDate": "/Date(1319144453250)/"}


CreateDate is recognized as null.

If I passed the JSON in this way, it works as expected:

{"CreateDate": "2011-10-10"}


The problem is that I cannot change client side code in an easy way, have to stick to /Date(1319144453250)/ this format. I have to make changes in server side.

How to solve this problem? Is that anything related to ModelBinder?

Thanks so much in advance!

Answer Source

The problem, as you suspected, is a model binding issue.

To work around it, create a custom type, and let's call it JsonDateTime. Because DateTime is a struct, you cannot inherit from it, so create the following class:

public class JsonDateTime
{
    public JsonDateTime(DateTime dateTime)
    {
        _dateTime = dateTime;
    }

    private DateTime _dateTime;

    public DateTime Value
    {
        get { return _dateTime; }
        set { _dateTime = value; }
    }
}

Change CreateDate to this type. Next, we need a custom model binder, like so:

public class JsonDateTimeModelBinder : IModelBinder  
{ 
    public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) 
    { 
        var value = bindingContext.ValueProvider.GetValue(bindingContext.ModelName).ToString(); 
        return new DateTime(Int64.Parse(
            value.Substring(6).Replace(")/",String.Empty))); // "borrowed" from skolima's answer
    }
}

Then, in Global.asax.cs, in Application_Start, register your custom ModelBinder:

ModelBinders.Binders.Add(typeof(JsonDateTime), new JsonDateTimeModelBinder());