43

多言語ASP.NETMVC3 Webアプリケーションの場合、コントローラーファクトリでThread.CurrentThread.CurrentCultureおよびを次のように決定しています。Thread.CurrentThread.CurrentUICulture

public class MyControllerFactory : DefaultControllerFactory {

    protected override IController GetControllerInstance(System.Web.Routing.RequestContext requestContext, Type controllerType) {

        //Get the {language} parameter in the RouteData
        string UILanguage;
        if (requestContext.RouteData.Values["language"] == null)
            UILanguage = "tr";
        else
            UILanguage = requestContext.RouteData.Values["language"].ToString();

        //Get the culture info of the language code
        CultureInfo culture = CultureInfo.CreateSpecificCulture(UILanguage);
        Thread.CurrentThread.CurrentCulture = culture;
        Thread.CurrentThread.CurrentUICulture = culture;

        return base.GetControllerInstance(requestContext, controllerType);
    }

}

上記のコードはもう1年近く経っています!だから、私は提案を開きます。

そして、私はこれを次のようにGlobal.asaxファイルに登録します。

ControllerBuilder.Current.SetControllerFactory(new MyControllerFactory());

これはうまく機能していますが、このタイプのアクションを実行するためのベストプラクティスであり、最適な場所であるかどうかはわかりません。

私はの主な役割を掘り下げていません、ControllerFactoryそして私はそれをと比較することができませんActionFilterAttribute

この種の行動をとるのに最適な場所についてどう思いますか?

4

5 に答える 5

57

これにはグローバルを使用しましたが、最近、メソッドで現在のカルチャを設定するのが遅すぎる場合があるActionFilterことに気付きました。OnActionExecutingたとえば、モデルの後に POST 要求がコントローラーに届くと、ASP.NET MVC はモデルのメタデータを作成します。アクションが実行される前に発生します。その結果、DisplayName属性値やその他のデータ注釈は、この時点でデフォルトのカルチャを使用して処理されます。

最終的に、現在のカルチャをカスタムIControllerActivator実装に設定するように移動しましたが、それは魅力のように機能します。今日のように、カスタム コントローラー ファクトリでこのロジックをホストすることは、リクエスト ライフサイクルの観点からはほぼ同じだと思います。global を使用するよりもはるかに信頼性が高くなりますActionFilter

CultureAwareControllerActivator.cs :

public class CultureAwareControllerActivator: IControllerActivator
{
    public IController Create(RequestContext requestContext, Type controllerType)
    {
        //Get the {language} parameter in the RouteData
        string language = requestContext.RouteData.Values["language"] == null ?
            "tr" : requestContext.RouteData.Values["language"].ToString();

        //Get the culture info of the language code
        CultureInfo culture = CultureInfo.GetCultureInfo(language);
        Thread.CurrentThread.CurrentCulture = culture;
        Thread.CurrentThread.CurrentUICulture = culture;

        return DependencyResolver.Current.GetService(controllerType) as IController;
    }
}

Global.asax.cs :

public class MvcApplication : System.Web.HttpApplication
{
    protected void Application_Start()
    {
        ...
        ControllerBuilder.Current.SetControllerFactory(new DefaultControllerFactory(new CultureAwareControllerActivator()));
    }
}
于 2012-06-16T15:35:19.767 に答える
4

これを配置する別の場所は、GlobalFilters コレクションに登録できるカスタム ActionFilter の OnActionExecuting メソッドにそのコードを配置することです。

http://weblogs.asp.net/gunnarpeipman/archive/2010/08/15/asp-net-mvc-3-global-action-filters.aspx

于 2011-11-22T12:19:13.543 に答える
0

ControllerActivator を使用しない場合は、BaseController クラスを使用して継承できます。

public class BaseController : Controller
{
    public BaseController()
    {
          //Set CurrentCulture and CurrentUICulture of the thread
    }
}

public class HomeController: BaseController    
{
    [HttpGet]
    public ActionResult Index()
    {
        //..............................................
    }
}
于 2019-04-17T14:17:49.203 に答える