I want to switch my views in MVC 3 between two languages – PL and EN. I’ve created two folders in Views- EN and PL. So after clicking appropriate language link at any site I want my route change from:
routes.MapRoute(
"pl", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "PL", action = "Index", id = UrlParameter.Optional } // Parameter defaults
);
to:
routes.MapRoute(
"en", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "EN", action = "Index", id = UrlParameter.Optional } // Parameter defaults
);
When I click appropriate link (language switcher) it changes CultureInfo which is persistent to all threads.
_Layout View with switcher:
<ul>
<li>@Html.ActionLink("En", "ChangeCulture", null, new { lang = "en"}, null)</li>
<li>@Html.ActionLink("Pl", "ChangeCulture", null, new { lang = "pl"}, null)</li>
</ul>
and controller (which sets also static variable lang that can be seen in every controller’s method and be persistent between requests):
public ActionResult ChangeCulture(string lang)
{
PLController.lang = lang;
CultureSettings setCulture = new CultureSettings();
setCulture.InitializeCulture(lang);
cookie.Value = CultureInfo.CurrentCulture.Name;
this.ControllerContext.HttpContext.Response.Cookies.Add(cookie);
return View("Index");
}
InitializeCulture method is overriden from Page class as follows:
public class CultureSettings : Page{
public void InitializeCulture(string culture)
{
String selectedLanguage;
if(culture == null)
{
selectedLanguage = "pl";
}
else
{
selectedLanguage = culture;
}
UICulture = selectedLanguage;
Culture = selectedLanguage;
Thread.CurrentThread.CurrentCulture =
CultureInfo.CreateSpecificCulture(selectedLanguage);
Thread.CurrentThread.CurrentUICulture = new
CultureInfo(selectedLanguage);
base.InitializeCulture();
}
}
It sets CultureInfo properly. Now I want (according to current CultureInfo) switch routes for every navigation links and change route pattern from mysite.com/PL/{controller}/{action} to mysite.com/EN/{controller}/{action}.
Does anyone has any ideas or maybe better approach for this problem? But condition is that address must be looking like this mysite.com/EN or mysite.com/PL – not different (i.e. en.mysite.com)
The first thing that you must decide is where to store the current user language. There are different possibilities:
IMHO for SEO purposes it’s best to have it as part of the url.
So I would recommend writing a custom route which will parse the language from the url and set the current thread culture:
We could now register this custom route in
Global.asax:Alright, now let’s have a model:
A controller:
And a view:
Now when you click on the links we are changing the language and this language is now part of the routes. Notice how once you have chosen the language this language is being persisted in the routes for the
testlink.Scott Hanselman also wrote a nice blog post on localization and globalization in ASP.NET that’s worth checking out.