Localizing Client-Side Data in a Web Forms Application
Problem
You need to format dates and currency values according to the culture of the client rather than the server.
Solution
Use client culture and encoding to return data to the client formatted according to the client's localization settings rather than the server's settings.
The sample code-behind for the Web Forms page contains one event handler and a single method:
Form.Load
Creates the CultureInformation object based on the user 's settings.
RefreshData( )
This method sets the CurrentCulture for the current thread and demonstrates the effect on output of different data types.
The C# code for the code-behind is shown in Example 3-5.
Example 3-5. File: ADOCookbookCS0305.aspx.cs
// Namespaces, variables, and constants using System; using System.Threading; using System.Globalization; using System.Data; using System.Data.SqlClient; // This value would normally be retrieved from a user profile. private String DEFAULTUSERCULTURE = "en-US"; private CultureInfo ci; // . . . private void Page_Load(object sender, System.EventArgs e) { if(!IsPostBack) ci = new CultureInfo(DEFAULTUSERCULTURE); else { // Create the CultureInfo object as specified by the user. if(enUsRadioButton.Checked) ci = new CultureInfo("en-US"); else if(enCaRadioButton.Checked) ci = new CultureInfo("en-CA"); else if(jaJpRadioButton.Checked) ci = new CultureInfo("ja-JP"); else if(frFrRadioButton.Checked) ci = new CultureInfo("fr-FR"); } RefreshData( ); } private void RefreshData( ) { if(ci != null) { // Set the culture for the current thread. Thread.CurrentThread.CurrentCulture = ci; // Retrieve details about the culture. cultureNameLabel.Text = CultureInfo.CurrentCulture.Name + " (" + Thread.CurrentThread.CurrentCulture.Name + ")"; cultureEnglishNameLabel.Text = CultureInfo.CurrentCulture.EnglishName; cultureNativeNameLabel.Text = CultureInfo.CurrentCulture.NativeName; } // Sample data that might come from a database // displayed according to culture set by user. dateLabel.Text = DateTime.Now.ToString("D"); shortDateLabel.Text = DateTime.Now.ToString("d"); Double d = 12345.678; numberLabel.Text = d.ToString( ); currencyLabel.Text = d.ToString("c"); }
Discussion
In a globalized application, a server can be processing requests for users around the world. Culture information for each user must be stored and made available to the server when it is processing each request from the user so that culture-specific operations are performed properly.
There are many ways to store the culture information for a user. You can store it persistently on the client in a cookie. Or you can store it in a database on the server and store it to a session variable when the client logs in or on an ad-hoc basis. No matter how the culture information is stored, it needs to be made available to the server as the client navigates through the site. For example, you can do this using session variables, the URL, or hidden fields. Once the server knows the culture of the user, it can use this information in culture-specific operations. Fortunately, .NET provides a collection of classes which makes this relatively easy.
The System.Globalization namespace contains classes that specify culture- related information. These classes are useful in writing globalized applications. Within this namespace, the CultureInfo class represents information about a specific culture and is used in culture-specific operations such as formatting numbers , currencies, and dates. The CultureInfo class has four constructor overloads, each allowing the culture to be specified differently. The sample code uses the constructor that takes the culture name in the format {languagecode2}-{country regioncode2} , in which:
languagecode2
Is the lowercase two-letter code derived from ISO 639-1.
country
Is the uppercase two-letter code derived from ISO 3166. If country is not available, the regioncode2 is used.
regioncode2
Is the three-letter code derived from ISO-639-2. regioncode2 is used when country is not available.
For example, the culture name for U.S. English is en-US .
Once the CultureInfo object is instantiated , you can assign it to the CurrentCulture property of the current thread by code with a SecurityPermission having the ControlThread flag set. Setting the CurrentCulture property affects subsequent culture-specific operations; setting it to the culture of the current user results in output specific to the user's culture.