Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Best place to set CurrentCulture for multilingual ASP.NET MVC web applications

For multilingual ASP.NET MVC 3 web application, I am determining the Thread.CurrentThread.CurrentCulture and Thread.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 against ActionFilterAttribute.

What do you think about the best place to do this type of action?

like image 318
tugberk Avatar asked Nov 22 '11 12:11

tugberk


People also ask

How will you set the culture and UI culture for asp net web page globalization?

To have ASP.NET set the UI culture and culture to the first language that is specified in the current browser settings, set UICulture and Culture to auto. Alternatively, you can set this value to auto:culture_info_name, where culture_info_name is a culture name. For a list of culture names, see CultureInfo.

What is the use of CurrentCulture property?

CurrentCulture property to retrieve and set the current culture. The CultureInfo object that this property returns is read-only. That means you can't mutate the existing object, for example, by changing the DateTimeFormat .


1 Answers

I used a global ActionFilter for this, but recently I realized, that setting the current culture in the OnActionExecuting 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 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()));     } } 
like image 116
s.ermakovich Avatar answered Sep 20 '22 00:09

s.ermakovich