Multilingual Applications in .NET - Part I

1. Introduction

This article provides a basic understanding of various methods of developing multilingual applications in .NET. Here emphasis is given to handling multiple languages using resource files. This also explains the necessary settings to be made in the Windows operating system and SQL Server database to support the multilingual capabilities.

2. General

Some of the approaches of developing multilingual applications are:

  • Develop the application or web pages for each language separately.
    Even though it is easy to host the application differently, the drawback is that keeping both the sets in sync even after a minor change is very difficult.
  • Store all the content in different languages in database tables.
    This approach solves the problem to a large extent but still requires more coding and database storage. This can have a performance issue also as the content is fetched from the db; but has the advantage of easy maintainability and also creation of the language on the fly. 
  • Store all the content in different languages in resource files.
    A resource is non-executable data required by an application and is deployed along with the application. This will have a better performance compared to fetching from the db; but deployment and new language support can be a little cumbersome since it requires more technical knowledge.

Based on the requirements and priorities, various approaches can be selected for development. This article discusses the use of resource files for development.

3. Approach

Before going into the details of how to create resources, we need to understand what is meant by "globalization", "localization" and "culture" in this context.

3.1 Globalization

Globalization is a process of identifying all the parts of your application that need to be different for respective languages and separate them from the core application.

3.2 Localization

Localization is the process of creating and configuring your application for a specific language.

3.3 Culture

A culture is the combination of the language that you speak and the geographical location you belong to. It also includes the way you represent dates, times and currencies. A culture is represented as shown in the following example:

en-US
en-GB
fr-BE

The first culture represents the English language as spoken in the US whereas the second culture represents the English language as spoken in Great Britain.

3.4 Namespaces

To work with culture information .NET provides a class called CultureInfo that resides in the System.Globalization namespace. The culture is set at thread level so you also need to work with the Thread class from the System.Threading namespace. Finally, for working with resources you need to use classes from System.Resources.

3.5 Setting the Culture and UI Culture for Windows Forms

Set the CurrentCulture and CurrentUICulture properties if you wish to override the settings of the user or operating system. In general, you would want to specify a culture so that every part of the application's user interface is appropriate to that culture. So you must set it before the InitializeComponent method is called.

// Put the using statements at the beginning of the code module
using System.Threading;
using System.Globalization;
// Put the following code before InitializeComponent()
// Sets the culture to French (France)
Thread.CurrentThread.CurrentCulture = new CultureInfo("fr-FR");
// Sets the UI culture to French (France)
Thread.CurrentThread.CurrentUICulture = new CultureInfo("fr-FR");

Note: The CurrentCulture property's default value is the system's User Locale that is set in the Regional Options Control Panel. The CurrentUICulture property's default value is the system's UI Language, that is the language of your system UI. On Windows 2000 and Windows XP Multilanguage Edition, the CurrentUICulture defaults to the current user UI language settings.

3.6 Setting the Culture and UI Culture for Web Forms

A Web Forms page has two culture values, Culture and UICulture. The Culture value determines or influences results of culture-dependent functions, such as displaying the date. The UICulture value determines how the resources are loaded for the form and is used for culture-specific lookup of resource data. The only purpose of the UICulture value is to indicate the language the resources should load; that is, determine which language the UI strings should use. The Culture value determines everything else; date formatting, number formatting, and so on.

To set the Culture and UI Culture values:

  • In the Globalization section of the Web.config file, add lines similar to the code below.
    culture="en-US"
    uiCulture="de"

    -Or-

  • In HTML view, add the Culture and UICulture values to the page directive.
    <%@ Page UICulture="de" Culture="en-US"...%>

  • In the Code Editor, add code to set the CurrentCulture and CurrentUICulture properties.

The following example sets both the CurrentCulture and the CurrentUICulture properties to the culture specified in the browser's Accept-Language header. Note that the CurrentCulture property is set using the CreateSpecificCulture method, since this property must be set to a specific culture and not a neutral culture.

// Import these namespaces at the beginning of the code module.
using System.Globalization;
using System.Threading;
// Set the culture and UI culture to the browser's accept language
Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture(Request.UserLanguages[0]);
Thread.CurrentThread.CurrentUICulture =
new CultureInfo(Request.UserLanguages[0]);

3.6 Resource Files

A resource is non-executable data that is required by the application and is deployed along with the application. For example Bitmaps, icons, cursors, screen labels. In order to create a resource file you need to first create a text/XML file containing the resource information and then compile it to get the actual resource file.

3.6.1 Types of Resource Files

The following are two types of files in which you can store resource information:

  • Text files: they are plain ASCII text files with key value pairs. They cannot hold binary data like images or objects. 
  • .resx files: They can contain text as well as binary data. They are actually XML files and can be used easily with Visual Studio.NET.

3.6.2 Creating "text only" Resource Files

Text resource files can be created with any text editor like Notepad. If you are using Visual Studio.NET then you can add a text file to a project and then add key-value pairs as shown below.

sample1.txt
label1=Hello World

3.6.3 Creating ".resx" Resource Files

To create .resx files Visual Studio.NET provides an easy way. Just "Add" > "New Item" > "Resource File" from the menu and enter keys and values in the resource editor.

A part of such file is shown below:

<data name="label1">
<value>Hello World</value>
</data>

Note that for all resource files the Build Action should be set to "Embedded Resource".

3.6.4 Creating Resource Files for different locales

The process of creating resource files for multiple locales is exactly the same as mentioned above. However, you need to follow certain naming conventions. The resource source files for different locales should have names matching the following syntax.

<base file name>.<locale>.txt
<base file name>.<locale>.resx

e.g
mymessage.en-US.txt
mymessage.en-GB.txt
mymessage.fr.txt

Note that a file without locale indicator forms the default resource file. For example mymessage.resources will form the default resource file for the application.

3.6.5 Compiling Resource Files

You can create a resource file by compiling the resource "source" files mentioned above using the ResGen utility that ships with the .NET SDK.

For example:

resgen mymessage.txt
resgen mymessage.resx

The above utility will create a mymessage.resources file after successful execution.

3.7 Satellite Assemblies

Satellite Assemblies are compiled DLLs that contain only resource data and no other code. Satellite assemblies can be created using the AL utility provided with the .NET SDK or you can use Visual Studio.NET to create them. They can be deployed at a later stage after the main application has been deployed. They are ideal for product based development wherein companies can come up with additional language support at a later date.

3.7.1 Reading resource from an assembly

To compile your resources in a satellite assembly, you need to use the following procedure:

  • Create a resource file (.txt or .resx) 
  • Compile into a resource files (.resource) 
  • Create a satellite assembly (.dll) using the AL command line tool 
  • Create folders for storing the satellite assembly 
  • Place the corresponding satellite assembly into the folders 
  • Access the resources inside the application

3.7.2 Creating Satellite Assemblies using AL utility

Using the AL command line utility you can embed your resources into an assembly. The assembly thus formed is nothing but a Satellite Assembly. The following code shows how this is done:

AL
/t:lib
/culture:en-GB
/embed:mymessage.en-GB.resources
/out:ResourcesDemo.resources.dll

Here, the /t switch specifies that the output is of type library (DLL). The culture switch specifies that the resources being embedded in the assembly are for the en-GB culture. The /embed switch specifies the .resources file that is to be embedded in the Satellite Assembly. Finally, the /out switch specifies the name of output assembly.

3.7.3 Creating Satellite Assemblies using the Visual Studio.NET utility

If you are using Visual Studio.NET then you can simply add the resource file to your project (library project) and make sure to set its action property in the property window to "Embedded Resource". At compile time Visual Studio.NET automatically embeds the resources inside the assembly being generated.

3.7.4 Creating folders for storing the Satellite Assembly

Satellite Assemblies can be dynamically loaded based on the current culture of your application. For this to work as expected, you need to follow a specific folder structure for the place Satellite Assemblies. You need to create a sub-folder inside the main folder of the application (in other words where the EXE of your application resides or the BIN folder for the ASP.NET application) with the same name as the culture. For example, if your Satellite Assembly is for the culture en-GB then you need to create a folder called en-GB and place the Satellite Assembly there.

3.7.5 Access the resources inside the application

In order to access a resource inside the Satellite Assembly, we will again use the ResourceManager class. The following code shows how this works:

Dim x As ResourceManager
Dim ci As New CultureInfo("en-GB")
Thread.CurrentThread.CurrentCulture = ci
x =
New ResourceManager("mymessage.en-GB",[Assembly].GetExecutingAssembly.GetSatelliteAssembly(ci))
Label1.Text=x.GetString("label1")

Here, we have created an instance of the CultureInfo class by passing a culture code "en-GB" to its constructor. Then we set this culture as the current culture of the running thread. We then create an instance of the ResourceManager class by specifying a resource base name. The second parameter of the ResourceManager constructor is of our interest. We are passing the Satellite Assembly that contains resources for the specified culture. We get this Satellite Assembly by the GetSatelliteAssembly() method of the executing assembly. Finally, we get a culture specific string by calling the GetString() method on the resource manager.

4. Windows Requirements

Windows 2000, XP and above are the best operating systems to support multilingual capabilities since they are completely UNICODE enabled. Even though the older versions of Windows is supported you will require the specific language edition of the operating system to support.

5. Setting up Windows 2000

To support multiple languages it is required to set up Language settings for the operating system.

"Language settings for the system" is available in "Start" => "Settings" => "Control Panel" => "Regional Options" and the "General" tab. Select the languages that are to be supported.

6. SQL Server Settings

To store the UNICODE data in the SQL Server database tables it is required to use the nvarchar and nchar datatypes.

7. Input Method Editors

IMEs are components that allow the user to enter the thousands of different characters used in East Asian languages using a standard 101-key keyboard. The user composes each character in one of several ways: by radical, by phonetic representation, or by typing in the character's numeric code-page index. IMEs are widely available; Windows 2000 and Windows XP ship with standard IMEs that are based on the most popular input methods used in each target country, and a number of third-party vendors sell IME packages.

Different IMEs can be added by using "Start" => "Settings" => "Control Panel" => "Regional Options" and the "Input Locales" tab.

8. References