有谁知道模型绑定何时发生在请求生命周期中?我问的原因是我遇到了一些本地化问题。
模型绑定是否在 OnActionExecuting 执行之前发生?
目前,我在全局操作过滤器 OnActionExecuting 方法中设置了当前区域性,但是在执行模型绑定时没有考虑到这一点。请求是一个 POST。
提前致谢。
有谁知道模型绑定何时发生在请求生命周期中?我问的原因是我遇到了一些本地化问题。
模型绑定是否在 OnActionExecuting 执行之前发生?
目前,我在全局操作过滤器 OnActionExecuting 方法中设置了当前区域性,但是在执行模型绑定时没有考虑到这一点。请求是一个 POST。
提前致谢。
我建议您将文化设置在更早的位置,而不是在操作过滤器中。在我当前的项目中,我Application_AcquireRequestState
在 Global.asax.cs 中设置了活动文化。你可以试试。
protected void Application_AcquireRequestState(Object sender, EventArgs e)
{
// set the culture
}
我发现在 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);
}
}
Alex Adamyan有一篇很棒的博客文章描述了这种技术。
另请参阅关于 SO 的问题和答案。
BindModel 先被击中。您的本地化可以根据请求进行更改吗?如果是这样,您可以覆盖默认模型绑定器,并在需要时在那里设置您的语言环境。按照下面的链接创建自定义模型绑定器
(为了证明自己,只需输入两个断点,您就会看到顺序)
我认为可能有更好的地方来设置本地化,但需要更具体的信息,这可能是一个不同的问题。
我也遇到了同样的问题。当模型绑定器具有无效数据时,它会在 ActionFilter(s) 之前运行。
我不喜欢建议的解决方案,因为弄乱路由不是我的首选解决方案。监听 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);
}
}
}