多言語ASP.NET MVC 3 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
と比較することはできません。
このタイプのアクションを行うのに最適な場所についてどう思いますか?
このためにグローバルActionFilter
を使用しましたが、最近、OnActionExecuting
メソッドで現在のカルチャを設定するのが遅すぎる場合があることに気付きました。たとえば、POST要求の後のモデルがコントローラーに来ると、ASP.NET MVCはモデルのメタデータを作成します。アクションが実行される前に発生します。その結果、DisplayName
この時点で、デフォルトのカルチャを使用して、属性値、およびその他のデータ注釈関連のものが処理されます。
最終的に、現在のカルチャをカスタムIControllerActivator
実装に設定しましたが、これは魅力のように機能します。今日のように、リクエストライフサイクルの観点から見ると、カスタムコントローラーファクトリでこのロジックをホストすることはほぼ同じだと思います。グローバル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()));
}
}
Anserが既に選択されていることを知っています。使用したオプションは、アプリケーションのOnBeginRequestイベントでスレッドの現在のカルチャを初期化するだけでした。これにより、すべてのリクエストで文化が発見されます
public void OnBeginRequest(object sender, EventArgs e)
{
var culture = YourMethodForDiscoveringCulutreUsingCookie();
System.Threading.Thread.CurrentThread.CurrentCulture = culture;
System.Threading.Thread.CurrentThread.CurrentUICulture = culture;
}
これを配置する別の場所は、GlobalFiltersコレクションに登録できるカスタムActionFilterのOnActionExecutingメソッドにそのコードを配置することです。
http://weblogs.asp.net/gunnarpeipman/archive/2010/08/15/asp-net-mvc-3-global-action-filters.aspx
OnActionExecuting
をオーバーライドする代わりに、ここでInitialize
をオーバーライドできます。
protected override void Initialize(RequestContext requestContext)
{
string culture = null;
var request = requestContext.HttpContext.Request;
string cultureName = null;
// Attempt to read the culture cookie from Request
HttpCookie cultureCookie = request.Cookies["_culture"];
if (cultureCookie != null)
cultureName = cultureCookie.Value;
else
cultureName = request.UserLanguages[0]; // obtain it from HTTP header AcceptLanguages
// Validate culture name
cultureName = CultureHelper.GetValidCulture(cultureName); // This is safe
if (request.QueryString.AllKeys.Contains("culture"))
{
culture = request.QueryString["culture"];
}
else
{
culture = cultureName;
}
Uitlity.CurrentUICulture = culture;
base.Initialize(requestContext);
}
ControllerActivatorを使用しない場合は、BaseControllerクラスを使用して、それから非表示にすることができます。
public class BaseController : Controller
{
public BaseController()
{
//Set CurrentCulture and CurrentUICulture of the thread
}
}
public class HomeController: BaseController
{
[HttpGet]
public ActionResult Index()
{
//..............................................
}
}