有没有人知道何时在请求生命周期中进行模型绑定?我问的原因是我遇到了一些本地化问题。
在执行OnActionExecuting之前是否发生了模型绑定?
目前,我将当前文化设置为全局操作过滤器OnActionExecuting方法,但在执行模型绑定时不会这样做。请求是POST。
提前致谢。
答案 0 :(得分:3)
我建议你在很早的时候设置文化而不是动作过滤器。在我目前的项目中,我在Global.asax.cs中的Application_AcquireRequestState
事件中设置了文化。你可以试试。
protected void Application_AcquireRequestState(Object sender, EventArgs e)
{
// set the culture
}
答案 1 :(得分:2)
我发现在MVC应用程序中,最好的方法是使用自定义路由处理程序并在该处理程序中设置文化。这与ModelBinders
以及数据注释中的本地化资源完美配合。
public class MultiCultureMvcRouteHandler : MvcRouteHandler
{
protected override IHttpHandler GetHttpHandler(RequestContext requestContext)
{
// get culture from route data
var culture = requestContext.RouteData.Values["culture"].ToString();
var ci = new CultureInfo(culture);
Thread.CurrentThread.CurrentUICulture = ci;
Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture(ci.Name);
return base.GetHttpHandler(requestContext);
}
}
有一个很好的blog article by Alex Adamyan描述了这种技术。
另请参阅SO上的this question & answers。
答案 2 :(得分:0)
首先点击BindModel 。您的本地化可以按要求更改吗?如果是,您可以覆盖默认的模型绑定器,如果需要,可以在那里设置您的语言环境。按照以下链接创建自定义模型绑定器
ASP.NET MVC Model Binder for Generic Type
(为了证明自己只是放了两个断点,你会看到订单)
我认为可能有更好的地方设置本地化但需要更具体的信息,这可能是一个不同的问题。
答案 3 :(得分:0)
我也遇到了同样的问题。当模型绑定器具有无效数据时,它将在ActionFilter之前运行。
我不喜欢提出的解决方案,因为弄乱路由不是我首选的解决方案。侦听Application_AcquireRequestState是有问题的,因为此事件会触发每个请求,而不仅仅是针对将被路由到MVC控制器的请求。
我最终编写了一个IControllerFactory
的自定义实现,在内部使用DefaultControllerFactory
并在CreateController
方法中执行本地化代码。
这也不理想,希望它有所帮助。
public class PluggableControllerFactory : IControllerFactory {
private readonly IControllerFactory innerControllerFactory;
public PluggableControllerFactory() {
innerControllerFactory = new DefaultControllerFactory();
}
public IController CreateController(System.Web.Routing.RequestContext requestContext, string controllerName) {
// Run your culture localization here
return innerControllerFactory.CreateController(requestContext, controllerName);
}
public System.Web.SessionState.SessionStateBehavior GetControllerSessionBehavior(System.Web.Routing.RequestContext requestContext, string controllerName) {
return innerControllerFactory.GetControllerSessionBehavior(requestContext, controllerName);
}
public void ReleaseController(IController controller) {
innerControllerFactory.ReleaseController(controller);
}
}
}