To create a Web application that can be multilingual was a complex task prior to ASP.NET v2.0. If you used resource files (RESX) and the ResourceManager, you needed to separate out localizable elements manually and perform your own resource loading, which required some effort and code. ASP.NET v2.0, simplifies this process greatly and brings a wealth of features such as:
When building a multilingual Web application, you benefit from a single page source that requires much less maintenance compared to the language-separated site or page structure. ASP.NET v2.0 accomplishes this by providing a declarative model for resource handling through resource expressions. Resource expressions are a sub-feature of the overall expressions feature, which can be thought of much like databinding expressions from ASP.NET v1.0. Expressions, however, are parse-time property setters that do not require the user to explicitly call a method like
- Auto detection of the Accept-Language HTTP request header field sent by the client browser
- Declarative resource expressions to tie controls or their properties to resources
- Programmatic access to resources and strongly-typed resources
- Automatic compilation and linking of RESX or RESOURCE files into runtime satellite assemblies
- Further design-time support for creation of resources
- A full extensibility model so that the RESX model can be swapped out
ASP.NET v2.0 provides automatic support for resource (RESX or RESOURCE) files that follow a specific naming convention and that reside in specialized folders within the application. This allows you to add resource files without any compilation step or satellite assemblies and allows you to provide resources that can be scoped to a page or an application. The ASP.NET runtime uses the .NET Framework
ResourceManager to perform resources lookup. This model has many advantages such as the automatic fall-back mechanisms and custom culture support.
If RESX resource files are not your preferred source format for storing translations, you'll find the entire model extensible.
The samples described here can be executed for English-US(en-US), French(fr), German(de), Spanish(es), Japanese(ja), and Arabic(ar) (Arabic only for the last two samples in the page). Other languages will defer to their fallback culture, or ultimately to English-US. Refer to Setting a Preferred Language in Internet Explorer in the previous topic so that you can see the use of resources in action.
A Simple Example New in 2.0
The following example demonstrates the localization of a Label control in a page called LabelLocalization.aspx.
<%@ Page UICulture="auto" Culture="auto" %>
<asp:Label ID="Label1" runat="server" Text="<%$ Resources:Label1TextKey %>"
Font-Name="<%$ Resources:Label1FontNameKey %>"/>
The page defines a
Page directive with specific
Culture attributes. The attribute values are automatic. This instructs ASP.NET to detect and set the current thread culture and UI culture for the page execution based on the preferred culture of the client browser. For a detailed explanation of how this works, see Auto-detecting the browser language for culture-sensitive formatting. As mentioned in the previous topic
Culture controls formatting of dates and numbers, whereas
UICulture controls resource loading - that is translated text and localized control properties like color or font.
Font-Name properties of the Label are bound to resource expressions that resolve to a resource key, which is used to perform assignment of the property to a value from, in this case, a local resource.
Alongside the LabelLocalization.aspx page is a peer folder called App_LocalResources. This is where the local resource(s) reside and are named appropriately for the page, for example:
These RESX files contain a keyname-value mapping. For example in LabelLocalization.aspx.resx
- LabelLocalization.aspx.resx. The culture-neutral resource file
- LabelLocalization.aspx.fr.resx. The culture-specific resource file, (French)
- LabelLocalization.aspx.de.resx. The culture-specific resource file, (German)
- LabelLocalization.aspx.ja.resx. The culture-specific resource file, (Japanese)
- LabelLocalization.aspx.ar.resx. The culture-specific resource file, (Arabic)
<value xml:space="preserve">Welcome to ASP.NET Localization</value>
Executing this page yields the rendering for the Label using a
Text property from the resource for German, French, Japanese, or other languages.
Resource Expressions New in 2.0
There are two forms of resource expressions, explicit and implicit.
|Resource Expression form||Description|
<%$ Resources:[filename prefix,]resource-key %>
The Explicit expression is used to define the value of a control property in declarative syntax, and the resource-key, which is required, is used to map to the value from the resource. The filename prefix parameter is optional, but the filename specifies the name of a resource file(s) that resides in the global resources folder.
<asp:Label ID="Label1" runat="server" meta:resourcekey="resource-key-prefix" />
The Implicit expression is used as an attribute on a control or object in declarative syntax and defines a resource-key-prefix, which is used to perform many property assignments for the control. The resource file contains many potential resource-keys of the general form resource-key-prefix.Property - for example, Label1KeyPrefix.Text and Label1KeyPrefix.Font-name. All resources are obtained from local resources only. You can think of the expressions as a short-hand notation for mapping one to many control properties without explicitly defining the properties in the page.
Global and Local Resources New in 2.0
Global resources reside in a specialized folder called
/App_GlobalResources, located at the root of the application. All pages, user-controls, etc. can access these resources, so they typically are used as shared resources. The name of the resource file is used in explicit expressions, but also forms the namespace.classname for strongly-typed access under the
Resources namespace in your application.
Local resources are defined in a peer-level
/App_LocalResources folder. RESX files follow the naming convention of the associated page, user-control, or master-page, along with the culture definition. For example,
foo.aspx will refer to the
/App_LocalResources/foo.aspx.resx culture-neutral file and
/App_LocalResources/foo.aspx.ja.resx culture-specific files. Only the associated page can access these resources using the explicit or implicit resource expression. There is a programmatic method available to access these resources in code.
Implicit Expressions to Local Resources New in 2.0
This sample was created from the sample showing culture-correct formatting by using Visual Web Developer to create the local resources. All text on the page was converted into ASP.NET Label controls, and after this the "Generate Local Resource" command from the Tools menu in design view generated the resource file for the default language (English-US in this case). This resource file was then translated to Japanese, German, French, and Spanish. No additional coding was necessary to enable the page for localization.
The designer added the
UICulture attribute to the
Page directive and implicit resource expressions like
<asp:Label ID="LabelTitle" runat="server" Text="Currency Exchange Calculator" meta:resourcekey="LabelResource1">
to enable the loading of resources during runtime.
The designer analyzes controls on the page for localizable resources. As the currency names on the page get filled in programmatically it cannot detect that they should be added to the localizable resources too - how this can be done manually is shown in a sample further down.
Localization using implicit expressions (VB)
Explicit Expressions to Local Resources New in 2.0
The page above using implicit expressions is still not completely translated - the currency names in the drop down and the exchange value list are still in English. Also the page is not yet translated to Arabic, and the German version should get a different background color for the title and date labels.
Arabic is a language that is written from right to left. To instruct the browser to display the page in the correct directionality, an additional resource called
HTMLDirectionality was added. Using an explicit expression to this local resource, the
dir attribute of the
html element of the page is set.
The following sample also uses explicit expressions to modify both
BackColor of the title and date labels. Note that the resources for languages that don't need to modify these values don't need to contain the resources - the fallback mechanism of .NET Framework resources will always pick up the default value contained in the default resources.
Programmatic Access to Global and Local Resources New in 2.0
Text that gets generated programmatically cannot be loaded by using resource expressions, nor can the Visual Web Developer designer automatically generate resources for it. ASP.NET offers the functions
GetLocalResourceObject() to deal programmatically with these cases. This is how the sample below loads the currency names from the added
CurrencyNames resources that are available application-wide.
Localizing Static Content New in 2.0
Typically developers create a Web application that contains static text as, for example the disclaimer on the page. It is not necessary to declare this as a
Label control, because a special
Localize control is available for this purpose. This control allows the editing of text not only in the property grid, but also directly in design view.
Localization using implicit and explicit expressions as well as programmatic access (VB)
Storing Language Preferences New in 2.0
In some cases the
UICulture selection defaults chosen by auto-detection might not be convenient for the user (e.g. a Spanish-speaking user using a computer in a Chinese Internet café). In these cases Web applications need to give users the option to change the displayed language and/or cultural preferences. The following sample shows how to build a
DropDownList control that lists all the available languages. It changes the language according to the selection in the drop-down and stores the selection using the new ASP.NET v2.0 Profiles feature.
It is important to note that changes to
Thread.CurrentThread.CurrentUICulture need to be made in the
InitializeCulture() method, because the auto-detection of the preferred browser language happens early during the page life cycle.
Selecting and storing language preferences using personalization (VB)