设置的CurrentCulture多语言ASP.NET MVC Web应用程序的最好的地方 [英] Best place to set CurrentCulture for multilingual ASP.NET MVC web applications
问题描述
对于多语言ASP.NET MVC 3 web应用程序,我确定 Thread.CurrentThread.CurrentCulture
和 Thread.CurrentThread.CurrentUICulture
的控制器工厂如下:
公共类MyControllerFactory:DefaultControllerFactory { 保护覆盖一个IController GetControllerInstance(System.Web.Routing.RequestContext的RequestContext,类型controllerType){ //获取的RouteData的{}语言参数
字符串的UILanguage;
如果(requestContext.RouteData.Values [语言] == NULL)
的UILanguage =TR;
其他
。的UILanguage = requestContext.RouteData.Values [语言]的ToString(); //获取语言code的文化信息
CultureInfo的文化= CultureInfo.CreateSpecificCulture(的UILanguage);
Thread.CurrentThread.CurrentCulture =文化;
Thread.CurrentThread.CurrentUICulture =文化; 返回base.GetControllerInstance(RequestContext的,controllerType);
}}
的上面code现在是近一年老了!所以,我开放的建议。的
块引用>和我注册这个在Global.asax文件,如:
ControllerBuilder.Current.SetControllerFactory(新MyControllerFactory());
这是工作不错,但我不知道这是否是最好的做法,做这类行动的最佳场所。
我没有挖成
的ControllerFactory
的主体作用,我无法把它比对ActionFilterAttribute
。你觉得做这类行动的最好的地方是什么?
解决方案我用一个全球性的
ActionFilter
这一点,但最近我意识到,设置当前文化在OnActionExecuting
方法在某些情况下,为时已晚。例如,当POST请求后的模型涉及到控制器,ASP.NET MVC创建模型的元数据。它发生在被执行任何操作之前。其结果是,显示名称
属性值等数据注解的东西使用默认的文化在这一点上的处理方式。最后,我搬到当前区域性设置为自定义的
IControllerActivator
实施,它的工作原理就像一个魅力。我想这是从请求生命周期的角度几乎相同举办这个逻辑在自定义控制器工厂,就像你今天。它更可靠,比使用全球ActionFilter
。CultureAwareControllerActivator.cs
公共类CultureAwareControllerActivator:IControllerActivator
{
公众一个IController创建(RequestContext的RequestContext的,类型controllerType)
{
//获取的RouteData的{}语言参数
String语言= requestContext.RouteData.Values [语言] == NULL?
TR:requestContext.RouteData.Values [语言]的ToString(); //获取语言code的文化信息
CultureInfo的文化= CultureInfo.GetCultureInfo(语言);
Thread.CurrentThread.CurrentCulture =文化;
Thread.CurrentThread.CurrentUICulture =文化; 返回DependencyResolver.Current.GetService(controllerType)作为一个IController;
}
}的Global.asax.cs
公共类MvcApplication:System.Web.HttpApplication
{
保护无效的Application_Start()
{
...
ControllerBuilder.Current.SetControllerFactory(新DefaultControllerFactory(新CultureAwareControllerActivator()));
}
}For multilingual ASP.NET MVC 3 web application, I am determining the
Thread.CurrentThread.CurrentCulture
andThread.CurrentThread.CurrentUICulture
on the controller factory as follows: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); } }
The above code is nearly a year old now! So, I open for suggestions.
And I register this on the Global.asax file like:
ControllerBuilder.Current.SetControllerFactory(new MyControllerFactory());
This is working good but I am not sure if it is the best practice and best place to do this type of action.
I haven't dug into the main role of
ControllerFactory
and I am unable to compare it againstActionFilterAttribute
.What do you think about the best place to do this type of action?
解决方案I used a global
ActionFilter
for this, but recently I realized, that setting the current culture in theOnActionExecuting
method is too late in some cases. For example, when model after POST request comes to the controller, ASP.NET MVC creates a metadata for model. It occurs before any actions get executed. As a result,DisplayName
attribute values, and other Data Annotations stuff are handled using the default culture at this point.Eventually I've moved setting the current culture to the custom
IControllerActivator
implementation, and it works like a charm. I suppose it's almost the same from the request lifecycle perspective to host this logic in the custom controller factory, like you have today. It's much more reliable, than usage of globalActionFilter
.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())); } }
这篇关于设置的CurrentCulture多语言ASP.NET MVC Web应用程序的最好的地方的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!