【问题标题】:ASP.NET MVC4 Model BindingASP.NET MVC4 模型绑定
【发布时间】:2012-10-09 09:55:08
【问题描述】:

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

模型绑定会在 OnActionExecuting 执行之前发生吗?

目前,我在全局操作过滤器 OnActionExecuting 方法中设置了当前区域性,但是在执行模型绑定时没有考虑到这一点。请求是一个 POST。

提前致谢。

【问题讨论】:

  • 我有完全相同的设置和问题,谢谢你的提问;)

标签: asp.net-mvc-4 action-filter


【解决方案1】:

我建议您将文化设置在更早的位置,而不是在操作过滤器中。在我当前的项目中,我在 Global.asax.cs 的 Application_AcquireRequestState 事件中设置了文化。你可以试试。

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

【讨论】:

  • 我想这确实是一个更好的解决方案。
  • 此解决方案适用于我,但现在这意味着此代码针对每个请求运行,而不仅仅是针对控制器的操作。请求的任何图像或 JS 文件现在都在运行此代码,这可能会影响性能。
【解决方案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

【讨论】:

    【解决方案3】:

    BindModel 首先被击中。您的本地化可以根据请求进行更改吗?如果是这样,您可以覆盖默认模型绑定器,并在需要时在此处设置您的语言环境。按照下面的链接创建自定义模型绑定器

    ASP.NET MVC Model Binder for Generic Type

    (为自己证明,只需在其中设置两个断点,您就会看到顺序)

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

    【讨论】:

      【解决方案4】:

      我也遇到了同样的问题。当模型绑定器有无效数据时,它会在 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);
          }
      
        }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-06-18
        • 1970-01-01
        相关资源
        最近更新 更多