
I have recently been working on a MVC / Bootstrap project, which is UK only.
Despite adding the following code to web.config, filling out a form with a DateTime in it still failed on a parsing error.
I had to set a custom model binder, because by default MVC doesn’t look at the current ui culture when model binding:
using System;
using System.Diagnostics;
using System.Threading;
using System.Web.Mvc;
namespace InsuranceDataArchiver.Infrastructure.ModelBinders
{
public class DateTimeModelBinder : IModelBinder
{
public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
var value = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);
Debug.Assert(value != null, "value != null");
bindingContext.ModelState.SetModelValue(bindingContext.ModelName, value);
try
{
var date = value.ConvertTo(typeof (DateTime), Thread.CurrentThread.CurrentUICulture);
return date;
}
catch (Exception ex)
{
bindingContext.ModelState.AddModelError(bindingContext.ModelName, ex);
return null;
}
}
}
public class NullableDateTimeModelBinder : IModelBinder
{
public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
var value = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);
if (value == null || string.IsNullOrWhiteSpace(value.AttemptedValue))
return null;
bindingContext.ModelState.SetModelValue(bindingContext.ModelName, value);
try
{
var date = value.ConvertTo(typeof(DateTime), Thread.CurrentThread.CurrentUICulture);
return date;
}
catch (Exception ex)
{
bindingContext.ModelState.AddModelError(bindingContext.ModelName, ex);
return null;
}
}
}
}
// then in Application_Start of global.asax
ModelBinders.Binders.Add(typeof(DateTime), new DateTimeModelBinder());
ModelBinders.Binders.Add(typeof(DateTime?), new NullableDateTimeModelBinder());
This has implications if you are using dates in URL’s, which I am not on this project, so it will suffice for now.
I also had to change the jquery validation, I installed the Jquery.Validation.AdditionalMethods nuget package and included the additional-methods.js script in my jQueryVal bundle:
@Html.LabelFor(m => m.FromDate, new { @class = "col-md-3 col-sm-6 col-xs-12 control-label" })
@Html.TextBoxFor(m => m.FromDate, new { @class = "form-control datepicker", id = "fromDate" })
@Html.LabelFor(m => m.ToDate, new { @class = "col-md-3 col-sm-6 col-xs-12 control-label" })
@Html.TextBoxFor(m => m.ToDate, new { @class = "form-control datepicker", id = "toDate" })
}
@section Scripts {
@Scripts.Render("~/bundles/jqueryval")
}
I get a feeling that this could be improved, but on my UK only site, I think its good for now. Note to self: read up on the way that URLs and model binding works. There may be a more elegant solution in there somewhere…
One Response to “MVC UK Date Issues”
Me
thanks for this I’ve been banging my head against keyboard for a week on what should have been a simple issue. I managed to get the client validation solved but didn’t realise MVC was ignoring ui culture too.