问题
Currently, I have a global filter called GlobalizationFilter
that checks the route values, cookies and browser languages header to determine the correct culture settings for the request:
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
// determine cultureInfo
Thread.CurrentThread.CurrentCulture = cultureInfo;
Thread.CurrentThread.CurrentUICulture = cultureInfo;
}
It all works, but the model binding process seems to occur before the global filters, and so the model binder doesn't take the culture settings into account.
This leads to problems with interpreting double values, DateTime
values etc.
I could move the culture detection code to other locations, but I don't like any of my options:
Application's
BeginRequest
event. At this point of time the routing hasn't occurred, so I'll have to manually fish out the/en-US/
culture token from the URL. This in unacceptable.Controller's
Initialize()
method. This will force me to write a base class for all my controllers, and inherit the existing controllers from it. I don't like this, but I'll opt for this solution if nothing better comes up.
Ideally, I want to find some way to inject my code between the "routing complete" and "model binding starts" events, but I found nothing in MSDN / Google on this.
Or maybe there's some other way to handle MVC3 globalization that I'm unaware of?
Thanks in advance for any contribution.
回答1:
Extract out the code that determines the culture into a separate component/class. Then create a ModelBinder
that derives from DefaultModelBinder
that uses the class to set the culture before calling BindModel
public class CultureAwareModelBinder : DefaultModelBinder
{
public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
/* code that determines the culture */
var cultureInfo = CultureHelper.GetCulture(controllerContext.HttpContext);
//set current thread culture
Thread.CurrentThread.CurrentCulture = cultureInfo;
Thread.CurrentThread.CurrentUICulture = cultureInfo;
return base.BindModel(controllerContext, bindingContext);
}
}
and then register it for the application (in Application_Start
)
// register our own model binder as the default
ModelBinders.Binders.DefaultBinder = new CultureAwareModelBinder();
来源:https://stackoverflow.com/questions/7202607/mvc3-globalization-need-global-filter-before-model-binding