2012-10-09 105 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); 
    } 

    } 
}