That’s all you need for basic date editing, though for your users’ sake I suggest you look at a nicer editor than the plain input that this will generate!

But what if you want to support some format besides the default? MVC doesn’t handle that out-of-the-box so you’ll need a custom model binder…

Custom Model Binder

The model binder is responsible for converting a series of form values into the rich, strongly-typed model that is passed as a parameter to your action method.

Thankfully there’s no need to re-implement all of the pretty-complex functionality involved in that process just to alter how dates are parsed; a custom model binder can be associated with a single type, and the rest of the binding functionality will work as normal.

Custom model binder implementations need to implement the IModelBinder interface, but the easier approach is to inherit from System.Web.Mvc.DefaultModelBinder and override the one method in which we are interested: BindModel

The BindModel method is responsible for returning the value of a model based on the controller- and the binding-context (which between them provide a lot of contextual information about the request), and our custom date parsing implementation will need to:

get hold of the custom format that we want to use

use that format with the value that has been posted back to the server

Specifying the Date Format

There are a lot of different ways in which you might determine or specify the custom format, but for the purposes of this example I am just going to pass it into the constructor.

Hooking it up

Now that we have the model binder, we need to associate it with all DateTime properties throughout our application. We do this by adding an instance of the binder to the ModelBinders.Binders collection from within Global.asax.cs.

This will associate our new binder with any properties or values of type DateTime or DateTime?. Now, whenever one of these types is encountered by MVC whilst trying to parse a POSTed value it will use our custom binder and therefore our custom format!

Share this:

Like this:

Related

Post navigation

11 thoughts on “Custom Date Formats and the MVC Model Binder”

Mark Van Mierlosays:

Can you please document the GetCustomDateFormat() method.
I don’t know how to implement it for my “nl-BE” locale, date format “dd/mm/yyyy”.
Jquery reverses day and month when it puts it in my ASP.NET MVC-model.
Thanks

The GetCustomDateFormat() method is expected to return a string similar to “en-US” or “nl-BE” – there is no complexity to it. I left it as a method because you could (in theory) get the date format from a number of places (e.g. config file, db, etc.)

If the problem is in your client-side JavaScript then I would recommend avoiding the whole problem and using a library like momentjs to explicitly set the format. JavaScript dates are a notorious pain to work with and momentjs is an easy win

I’m trying to match JQGRID to a MVC4 WEB API.
The JQGrid as is returns a date as “dd/mm/yyyy”
I don’t know what is easiest :
– fitting moment.js into jqgrid.js at the client or
– adapting the server-side model binding.
As for the second approach : using your method with
var binder = new DateTimeModelBinder(“nl-BE”);
has no effect. This culture is also defined in Web.config.

You’re right – my comment above is incorrect. GetCustomDateFormat should return the *date format*, not the culture. You can get the culture using new CultureInfo(“en-US”).DateTimeFormat.ShortDatePattern

I think that the best approach in this case is to use a consistent date format (such as yyyy-MM-dd) for all transfer. Otherwise you will have problems if the culture on either your server or one of your clients is ever something unexpected.

Thanks again.
I tried the following in Global.asax.cs :
var cultureFormat = new CultureInfo(“nl-BE”).DateTimeFormat.ShortDatePattern;
var binder = new DateTimeModelBinder(cultureFormat);
No change.

I’m exploring the possibilities of MVC4 and JQGrid for a local Intranet-application, So diverging timezones are not an issue. Getting valid dates back from the client is.
Sending dates to the client is no problem, I tried a lot of different formats and now use ISO8601Long.
However JQGrid seems to send back (POST or OUT) only in one format : “mm/dd/yyyy”.
I didn’t find out yet which module does the parsing: jqgrid, jquery or the browser.
I realize this is a JQGrid-issue but I thought to tackle it with your binding-solution. ;-)

The method signatures in my Web API-controller are :
public HttpResponseMessage Put(int id, Product item)
and
public HttpResponseMessage Post(Product item)
There is only one DateTime-field in the model.

I placed a breakpoint in the BindModel-method and it indeed is not hit.
Have I missed something ?
I just created the DateTimeModelBinder-class and initated it in Global.asax.

Ah, In suspect the problem is in fact that WebAPI uses different base classes to MVC, and the code in this post is for MVC.

You should still be able to create a custom binder for WebAPI – you’ll just need to implement System.Web.Http.IModelBinder instead of System.Web.Mvc.IModelBinder. I’ve not looked at it but I assume it’s a fairly similar interface