The site is currently in read-only mode for maintenance. Posting of new items will be available again shortly.
If you believe that your web application is going to be used by people coming from different countries, speaking different languages, you might want to consider offering the Language Selection feature. It is a very common feature in all international applications and it is quite easy to implement in .NET 4 Web Applications.
This is an improved (second version) of the article, after comments that I received from members and in particular graffic.
What such a feature should be composed of?
This is the bare minimum list:
- Automatic detection of the language preference of the user as set in his browser.
- A way for the user to change the language of the user interface while inside your application.
- When the user changes the language, the current page that the user is viewing should not be lost and the user should not be directed to a default page.
- The language selected needs to persist among page views. We should not expect, undoubtedly, the user to set the language he prefers on every page that he visits.
- At least, all the labels in your web application should be presented in the user selected language.
Automatic detection of the language preference of the user as set in his browser
In your web.config file, you need to set the following globalization tag with the values that are presented below:
Believe it or not, this is enough to have the user use his preferred language with your web application. However, not all users know how to set the language preference in their browser and usually expect a way to select their preferred language using something like an image or link or drop down select box on your web application.
Allow user to select language while on your web application
Language selection module
First of all, you need to implement a language selection module on your server.
public class LanguageModule:IHttpModule
public void Init(HttpApplication context)
context.AcquireRequestState += new EventHandler(OnAcquireRequestState);
public void Dispose()
public void OnAcquireRequestState(Object i_object, EventArgs i_eventArgs)
HttpApplication l_httpApplication = i_object as HttpApplication;
var l_language =
var l_boolLanguageChanged = false;
if (l_language == null)
l_language = (string)l_httpApplication.Session[Constants.SESSION_LANGUAGE];
l_boolLanguageChanged = true;
var l_culture = new System.Globalization.CultureInfo(l_language);
Thread.CurrentThread.CurrentCulture = l_culture;
Thread.CurrentThread.CurrentUICulture = l_culture;
l_httpApplication.Session[Constants.SESSION_LANGUAGE] = l_language;
if (l_boolLanguageChanged && l_httpApplication.Request.UrlReferrer != null)
What is going on here? The module registers an
AcquireRequestState* and makes sure that it either uses a language parameter passed over the request or language stored in
Session from any previous requests. Having set the local variable
l_language, it creates the necessary
CultureInfo object and sets it to
CurrentUICulture. Then, it saves the selection in the
Session and redirects to the page where the user was when he selected to change the language. Note that redirection takes place only when the user actually asks for a change of language (by passing the language parameter in their request). Otherwise, redirection does not take place.
AcquireRequestState is the point in the request handling process that we have the Session available for handling.
Since you are making an
HTTPModule, do not forget to tell your .NET runtime that you want it in the request handling chain. This is done with a special entry in the web.config file. Here is the one in the demo (it is in the
<add name="LanguageSettingModule" type="LanguageModule, App_Code" />
UI to change language
This is up to your choice and taste. Do it the way you want and like most. In any case, you should find a way to send a request to the server like the following:
which is used to select Greek. Or:
which is used to select English, and so on. In the demo code that accompanies this article, I have introduced a piece of code on my Master page that allows the user to select one of these three languages: Greek, English, Russian. Here is the piece of code in my Master ASPX page (I put such code in Master so that it is available in all of the pages in my web site):
<%@ Master Language="C#" AutoEventWireup="true"
CodeFile="MasterPage.master.cs" Inherits="MasterPage" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
<asp:ContentPlaceHolder id="head" runat="server">
<form id="form1" runat="server">
<asp:HyperLink ID="hprlnkGreek" runat="server"
<asp:HyperLink ID="hprlnkEnglish" runat="server"
<asp:HyperLink ID="hprlnkRussian" runat="server"
<asp:ContentPlaceHolder id="ContentPlaceHolder1" runat="server">
Save user selected language in Session
As you saw before, in the code of the language selection module, we store the language that the user has selected in the Session. This needs a small preparation.
- Create a constant for the key that is used to store the language in Session. I have done this in a special class called
Constants. Here is the code:
public class Constants
public const string SESSION_LANGUAGE = "language";
- In my Global.asax, I create the key and set it to the currently selected UI Culture language, as follows:
void Session_Start(object sender, EventArgs e)
Finally, you need to make your Labels multilingual. This is a five step process:
- Create an ASP.NET folder in your project. The folder type need to be
- Add a new item
ResourceFile. The name of this file should not contain any language specification. For example, LocalizedResources.resx. This file will hold the strings of the default language of your web site. In the demo, the default language is English.
- Add a new item
ResourceFile for each (besides the default) language that you want to support. Each language specific file needs to have a language specification in the filename. For example, the Russian file has to have the name LocalizedResources.ru.resx. Do you see the .ru.? It is for the Russian language. Or, for Greek, the file has to be LocalizedResources.el.resx. Do you see the .el.?
- These files will need to contain all the strings that you need to have multilingual support. The default resource file will has the translation in the default language of your site. The other resource files will have the translations in the corresponding languages.
- Then you need to use the resource strings and not write label values by hand inside your code. See for example the Customers.aspx file and how the
Firstname label is built:
<asp:Label ID="lblFirstname" runat="server"
Text="<%$ Resources:LocalizedResources, Firstname %>" />
Do you see how the
Text property is set?
Firstname is a localized string that has a translation in all the resource files of my demo project. Easy, right?
Then, it is all .NET magic. The Labels will display the correct string/translation according to the user selected language.
Tips to improve user experience with regards to language selection
This is a start. You can improve the user experience with regards to language selection as follows:
- Save the language that the user has selected in a cookie. So the next time the user comes to your web application, even if he does not set the preferred language in his browser, you will be able to set the language to the language that the user chose in his previous visit to your site.
- Alternatively, you can save this selection to the user preferences table in your database.
- Multilingual resources and the way .NET manages them is quite powerful. You are not only restricted to multilingual strings. Depending on the language selected, you can:
- display different images
- use different icons
- playback different audio files
- reference different external files
I believe that we covered all the feature requirements as set here. I hope that this article puts you in start and you can make your applications multilingual and get international users.
- May 14th, 2011 - Second release of the article that uses an HTTPModule to handle the change of language.
- May 7th, 2011 - First release of the article.