リクエストのライフサイクルでモデルバインディングがいつ行われるか知っている人はいますか? 私が質問する理由は、ローカリゼーションの問題に直面しているためです。
モデル バインドは 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);
}
}
この手法を説明するAlexAdamyanによる優れたブログ記事があります。
SOに関するこの質問と回答も参照してください。
私も同じ問題に遭遇します。モデル バインダーに無効なデータがある場合、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);
}
}
}
BindModel が最初にヒットします。リクエストごとにローカリゼーションを変更できますか? その場合は、デフォルトのモデル バインダーをオーバーライドし、必要に応じてロケールを設定できます。カスタム モデル バインダーの作成については、以下のリンクを参照してください。
ジェネリック型の ASP.NET MVC モデル バインダー
(自分で証明するために、2 つのブレークポイントを入れるだけで、順序が表示されます)
ローカリゼーションを設定するためのより良い場所があるかもしれないと考えていますが、より具体的な情報が必要であり、それは別の質問かもしれません.