2012-10-09 106 views
7

有谁知道模型绑定何时发生在请求生命周期中?我问的原因是我遇到了一些本地化问题。ASP.NET MVC4模型绑定

确实模型绑定OnActionExecuting发生之前执行?

目前我设置一个全球行动当前的文化过滤OnActionExecuting的方法,但在执行模型绑定时,这是不被尊重。该请求是POST。

在此先感谢。

+0

我有确切相同的设置和问题,谢谢大家问;) –

回答

0

BindModel是先出手。您的本地化可以根据要求更改吗如果是这样,您可以覆盖默认模型联编程序,并在需要时设置您的语言环境。按照上创建自定义的模型绑定以下链接

ASP.NET MVC Model Binder for Generic Type

(来证明自己只是把两个断点中,你会看到订单)

我想有可能是一个更好的地方设置本地化,但需要更具体的信息,这可能是一个不同的问题。

3

我建议你设置文化在一个非常早的点,而不是在行动过滤器。在我目前的项目中,我在Global.asax.cs的Application_AcquireRequestState事件中设置了文化。你可以试试。

protected void Application_AcquireRequestState(Object sender, EventArgs e) 
{ 
    // set the culture 
} 
+0

我想这确实是一个更好的解决方案。 –

+0

该解决方案适用于我,但现在这意味着此代码针对每个请求运行,而不仅仅是控制器的操作。所请求的任何图像或JS文件现在都在运行此代码,这可能会影响性能。 –

2

我发现,在MVC应用程序的最佳方法是使用一个定制routehandler并设置文化在处理程序。这与数据注释中的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

0

我也遇到了同样的问题。当模型联编程序具有无效数据时,它将在ActionFilter(s)之前运行。

我不喜欢所提出的解决方案,因为搞乱路由选择并不是我的首选解决方案。监听Application_AcquireRequestState是有问题的,因为这个事件触发每个请求,而不仅仅是发送到MVC控制器的请求。

我最终编写了一个内部使用DefaultControllerFactory的自定义实现IControllerFactory,并在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); 
    } 

    } 
}