In ASP.NET, and in particular in the class Page, there are two properties with a similar name -- Culture and UICulture -- that are both necessary when you want to support multiple languages in a page. Both properties are of type String, but can only be assigned some predefined culture names and not just any strings. Culture identifiers are made by two tokens -- the culture name and language name. For example, the string "en-US" indicates the English culture and the U.S. language, whereas "en-GB" stands for English culture and the Great Britain language.
What's the purpose of having two string properties to get and set the requested language and culture for an ASP.NET page? Quite simply, the two properties refer to distinct capabilities and impact on different areas of the user interface.
- The Culture property affects the results of functions such as date, number, and currency formatting.
- The UICulture property determines the localized resource file from which page resources are loaded.
The two culture properties may or may not have the same value. This possibility results in a higher level of flexibility for your code. For example, you can switch the language of text and messages according to the browser's configuration while leaving globalization settings (such as dates and currency) constant.
You set culture properties using attributes of the @Page directive:
<%@ Page UICulture="it-IT" Culture="en-US" %>
Culture settings are page-specific; however, to automatically apply the same settings to all pages in the application you can use the <globalization> section of the web.config file:
<globalization uiculture="it" culture="it-IT" / >
It is important to note that the @Page directive and globalization section are the primary ways to set culture information programmatically. The Culture and UICulture properties exposed by the Page class, although public and read/write, are not intended for use in application code. This means that you are encouraged to use them in internal page code, but not directly from the code-behind. If you need to "multi-language" Web sites, you can derive your pages from a custom base class and add some custom logic to it where you manipulate culture properties. You should not do so, though, if all that you need is setting a fixed culture.
When you set culture properties in @Page or web.config you can also employ a very special value -- auto -- which will perform automatic detection of the browser's preferred language and set properties accordingly. You change the browser's language preference by selecting the Options menu and then the Language tab. After that, you refresh the page, or restart the browser, and the new settings are in place.
It is also essential to note that simply setting Culture and UICulture properties on the Page class is not enough to actually make the language switch. To programmatically change culture settings you need to do the following:
- Override the InitializeCulture method on the code-behind class, or from any custom class that inherits from Page.
- In the method, you set both the page's culture properties and the culture information on the current thread.
The InitializeCulture method is protected and overridable; in the method you set page and thread properties.
protected override void InitializeCulture() { string lang = GetLanguageFromSomeSource(); this.UICulture = lang; this.Culture = lang; Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture(lang); Thread.CurrentThread.CurrentUICulture = CultureInfo.CreateSpecificCulture(lang); base.InitializeCulture(); }
The thread's CurrentCulture property requires a CultureInfo. It is key to note that the InitializeCulture method is invoked pretty soon in the page lifecycle. When it gets called, you have no access built yet to page controls. If the language is being passed on the query string or a form field, you can only access those values through Request collections. If you go through InitializeCulture, by design, you are guaranteed that any user interface is only rendered after the culture has been set.