Skip to content

Detect the user's locale

shiftkey edited this page Feb 29, 2012 · 1 revision

To ensure you are serving the right content to the right user, your application should detect the locale that is provided by the user's browser. Rather than hard-coding this check into every request, there are a number of options available for detecting this during the request lifecycle and keeping the plumbing code separate from the application code.

web.config

The easiest way to detect the user's locale is to enable it at the site-level.

Add the following snippet inside the system.web node:

<system.web>
   <globalization enableClientBasedCulture="true" uiCulture="auto" culture="auto" />
</system.web>

Pros:

  • Easy to implement - no code changes necessary.

Cons:

  • Cannot override - testing a different locale becomes harder

Custom cookies

The easiest way to override the application is to detect a specific cookie to specify and override the default locale with the value it specifies.

The package includes a base controller which takes care of that task:

public abstract class BaseController : Controller
{
    protected override IAsyncResult BeginExecute(RequestContext requestContext, AsyncCallback callback, object state)
    {
        var request = requestContext.HttpContext.Request;
        string cultureName = null;
        var cultureCookie = request.Cookies["_culture"];
        if (request.UserLanguages != null)
            cultureName = cultureCookie != null ? cultureCookie.Value : request.UserLanguages[0];
        cultureName = CultureHelper.GetImplementedCulture(cultureName); // This is safe
        Thread.CurrentThread.CurrentCulture = new System.Globalization.CultureInfo(cultureName);
        Thread.CurrentThread.CurrentUICulture = Thread.CurrentThread.CurrentCulture;

        return base.BeginExecute(requestContext, callback, state);
    }
}

Then on the client you could create a UI to select the language and populate a cookie:

$('.language a').click(function () {
   if ($(this).hasClass(Globalize.culture().name.toLowerCase()))
       return false;
   $.cookie("_culture", $(this).attr("class"), { expires: 365, path: '/' /*, domain: 'example.com' */ });
       window.location.reload(); // reload 
       return false;
});

We are using the jquery.globalize plugin to simplify the client-side management of resources. More on that here. TODO: link to another page.

Pros:

  • Better testing - users can switch languages inside the application.
  • Fallback to browser's locale.

Cons:

  • Controllers need to subclass BaseController
  • Changes in MVC4 (asynchronous controllers by default) requires us to adapt the BaseController for MVC3 and MVC4.
Clone this wiki locally