Well, I think it is about time I update the localisation post I have on my blog; so many people had sent me messages saying it is overly complicated or outdated and I completely agree with them…I wrote the thing in early 2009! Caveat emptor: This solution is what I use in many projects; it might not be the best solution but it works for me and if it works for you, good! Otherwise, there are plenty of other good solutions out there such as this one. Moreover, if you are looking for something with multi-locale content from a database this solution is definitely not for you. Let us move away from the ordinary two languages website. This one is going to be five locales, French, English, Spanish, Portuguese and Japanese so we can play with different character sets. Here is an outline of what we need to do:
  1. Create an MVC 4 project.
  2. Create a mechanism to tell the website in which language we want to display.
  3. Create user interface components to allow for language switching.
  4. Create a controller action to handle language switching.
  5. Create resources files and localize views.
  6. Friendly localized URLs for SEO
  7. Localization of models.
  8. Form validation.

1. Create an MVC 4 project.

Lets fire up Visual Studio and create a new MVC 4 project. For simplicity, I will use the Internet Application template and because it is awesome I will use Razor.

Create project

 2. Create a mechanism to tell the website in which language we want to display.

I will do this in Global.asax file under the Application_AcquireRequestState event.
protected void Application_AcquireRequestState(object sender, EventArgs e)
{
    var handler = Context.Handler as MvcHandler;
    var routeData = handler != null ? handler.RequestContext.RouteData : null;
    var routeCulture = routeData != null ? routeData.Values["culture"].ToString() : null;
    var languageCookie = HttpContext.Current.Request.Cookies["lang"];
    var userLanguages = HttpContext.Current.Request.UserLanguages;

    // Set the Culture based on a route, a cookie or the browser settings,
   // or default value if something went wrong
   var cultureInfo = new CultureInfo(
       routeCulture ?? (languageCookie != null
          ? languageCookie.Value
          : userLanguages != null
              ? userLanguages[0]
              : "en")
   );

    Thread.CurrentThread.CurrentUICulture = cultureInfo;
    Thread.CurrentThread.CurrentCulture =    CultureInfo.CreateSpecificCulture(cultureInfo.Name);
}

3. Create user interface components to allow for language switching.

There is many solution to do this, I simply created a drop down menu with a link for each language. menu language ui

4. Create a controller action to handle language switching.

All we need to do here is update the language cookie with the user selected culture, once this is done we will redirect to the user to his previous location. This code will reside in the Home controller.
public ActionResult ChangeCulture(string lang)
{
    var langCookie = new HttpCookie("lang", lang) { HttpOnly = true };
    Response.AppendCookie(langCookie);
    return RedirectToAction("Index", "Home", new {culture = lang});
}

5. Create resources files and localize views

We will not be using the special folder App_GlobalResources or App_LocalResources, you can find out why here. Instead we will create a Resources folder in the project. Create the following resources files:
  • English: Home.resx
  • French: Home.fr.resx
  • Spanish: Home.es.resx
  • Portuguese: Home.pt.resx
  • Japanese: Home.ja.resx
The generated code for these is private by default, we will need to change that so they are public, we will also give them a custom namespace for easy access. Select the files and open the property window, the properties should be as follows: Build Action: Embedded Resource Custom Tool: PublicResXFileCodeGenerator Custom Tool Namespace: Resources properties  

6. Friendly localized URL for SEO

This part is already managed in step 2. All we need to do now is handle requests with the culture in them, to do so we need to modify the default route to include the culture.
routes.MapRoute(
    name: "Default",
    url: "{culture}/{controller}/{action}/{id}",
    defaults: new { culture = "en", controller = "Home", action = "Index", id =      UrlParameter.Optional }
);

7. Localization of models.

Coming soon…

8. Form validation.

Coming soon…