ASP.NET MVC4模型绑定

时间:2012-10-09 09:55:09

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

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

在执行OnActionExecuting之前是否发生了模型绑定?

目前,我将当前文化设置为全局操作过滤器OnActionExecuting方法,但在执行模型绑定时不会这样做。请求是POST。

提前致谢。

4 个答案:

答案 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);
    }

  }
}