Introduction

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.

Implementation

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.

What is going on here? The module registers an EventHandler on 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 Thread.CurrentThread.CurrentCulture and 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 system.web section):

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:

http://www.mymultilingualsite.com/?language=el

which is used to select Greek. Or:

http://www.mymultilingualsite.com/?language=en

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):

Multilingual Labels

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 App_GlobalResources.

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:

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

Conclusion

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.

History

May 14th, 2011 - Second release of the article that uses an HTTPModule to handle the change of language.

Your code is really help me but I got an error when I add external stylesheet into my project. And here is an error:
Session state is not available in this context.
Line 25: If l_language Is Nothing Then
Line 26: ' if language parameter is not sent, then take language from session
Line 27: l_language = DirectCast(l_httpApplication.Session(Constants.SESSION_LANGUAGE), String)
Line 28: Else
Line 29: ' If language parameter is indeed sent, then user wants to change language.

I went to debug it using the built-in debugger in Visual Studio 2010 (VS) and received an error that the class module cannot be loaded. I know it is finding the module because if I move it to a different location in my project, it specifies that it cannot find the module.

This got me thinking about the whole subject of httpModules and their deployment on a localhost webserver and also use in VS debugging and I now have the following questions as a new and aspiring .NET programmer -

1. Does using the VS debugger make a difference? Does for example the module need to be registered separately ahead of time somehow on the localhost? Does it make a difference that the web.config file, the class module for the LanguageModule and the page itself (as well as the App_GlobalResources files) are all inside the same VS project?
2. Does the httpModule need to be registered separately on the local IIS for the application? I mean, I'm sure it needs to be so registered if I am running the application in a browser outside of Visual Studio, - but what about from within VS using the debugger? Doesn't the built-in compiler in the Debugger handle this (registration)?
3. If none of the above are issues in using the VS debugger, how can I go about debugging why the module won't load?

Sir,This tutorial is of great help and most importantly to a beginner like me also.But my problem is that I have a dropdownlist of languages.When user changes the language to one the page is loading or what we call !IsPostBack(not reloading or getting IsPostBack) again.So, all the changes made by the user get vanished and as the view state is also expiring the dropdownlist also shows the first language(not the one selected by the user).So, is there a way to get this feature without the page load(!IsPostBack) and only with reload(IsPostBack)?Thanks in advance and regards.

Set the language earlier.
In you example you set the language in a base page. This means ashx and asmx won't use the right language. You can use the global.asax or an HttpModule to set the language from the start.

Don't even set it, use it
Setting the language from a base page or from an http module means that "magically" applications have the language set. Static magic works for all applications and modules. But when it comes to testing you have to emulate the magic of the static setting somewhere in the environment and remember to clean things up. (Check this link: Service Locator as an anti-pattern)

Dependency injection can automate the work of looking for the right language, setting it somewhere, and building everything that is language related. I leave you an example of an Application_Start configuration for an MVC .NET application.

Use gettext
This comment goes outside the scope of your article. Give a try to gettext, or at least the way applications are built using gettext. You'll get automated translated string translations without the hassle of: "I've changed one string... open all the resx files, add it". Also you can get really nice tools to manage translations like: http://www.transifex.net