It's way too late to set the current culture in the model binder. This should be done much earlier in the execution pipeline. For example in the Application_BeginRequest
event in your Global.asax
.
Thread.Culture not being respected for model-binding in MVC2
-
31-05-2022 - |
Question
To allow for culture-specific values to be bound correctly I have this ModelBinder:
public class CultureAwareModelBinder : DefaultModelBinder {
public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) {
BaseController controller = (BaseController)controllerContext.Controller;
CultureInfo culture = controller.Settings.Culture;
CultureInfo language = controller.Settings.Language;
Thread.CurrentThread.CurrentCulture = culture;
Thread.CurrentThread.CurrentUICulture = language;
return base.BindModel(controllerContext, bindingContext);
}
}
(BaseController.Settings
is a property that exposes the correct CultureInfo
for the current application's user).
I set it up like so
protected void Application_Start() {
ModelBinders.Binders.DefaultBinder = new CultureAwareModelBinder();
}
When I debug and step-through my code, the Thread.Culture is being set correctly, however my model keeps getting the wrong values.
This is my model:
public class EventModel {
public DateTime Start { get; set; }
public DateTime End { get; set; }
}
When I specify "10/6/2013" for either field in my web-browser and hit submit, and when the culture is "en-GB" (and I checked the thread's DateTimeFormat is indeed set to dd/MM/yyyy
), MVC receives it as the 6th October 2013, not the 10th June 2013.
I don't know why this is happening, and unfortunately I can't source-step into the actual model-binding. Why is it not respecting the thread culture?
Solution
OTHER TIPS
I faced the same issue. My solution was to use the DefaultModelBinder
however instead of using an ActionFilter
to set the desired culture I used a IAuthorizationFilter
which has the same effect, however is executed before model binding unlike the 'ActionFilter' which is executed after model binding.
I appreciate that it is slightly inelegant/unorthodox use of the IAuthorizationFilter
however it did the trick.