Globalization and Localization in .NET

Globalization, Localization

To implementing a multilingual user interface, you design the user interface to open in the default UI language and offer the option to change to other languages.

Globalization is the first step in the process. A globalized application supports localized user interfaces and regional data for all users. Truly global applications should be culture-neutral and language-neutral. A globalized application can correctly accept, process, and display a worldwide assortment of scripts, data formats, and languages.

While your globalized application may possess such flexibility, ensure that you have separated the application's resources that require translation from the rest of the application's code. If you correctly test for localizability before proceeding to the localization step, you should not need to modify your application's source code during localization.

Globalization in .Net: CultureInfo, ResourceManager and Resgen

In .Net the System.Globalization namespace contains classes that define culture-related information, including the language, the country/region, the calendars in use, the format patterns for dates, currency and numbers and the sort order for strings. There are around 20 classes in System.Globalization. Here we are only concern to CutureInfo class.

The CutureInfo class represents information about a specific culture including the names of the culture, the writing system, and the calendar used, as well as access to culture-specific objects that provide information for common operations, such as formatting dates and sorting strings.

The System.Resources namespace provides classes and interfaces that allow developers to create, store, and manage various culture-specific resources used in an application. One of the most important classes of the System.Resources namespace is the ResourceManager class. The ResourceManager class allows the user to access and control resources stored in the main assembly or in resource satellite assemblies

The Resource File Generator (Resgen.exe) converts .txt files and .resx (XML-based resource format) files to common language runtime binary .resources files that can be embedded in a runtime binary executable or compiled into satellite assemblies.

Creating  .resources files

To proceed with our example, let us first create the .resources files. Here I am using the six languages English, French, German, Spanish, Italian and Portuguese (Thanks to Google for this and don''t blame me if there is anything wrong in the conversion). To create .resources files create the following six .txt files in any folder as follows.

resource.en-US.txt: that contains the following English text.

0001=Please Enter User Name
0002=Please Enter Password
0003=User Login
0004=Submit
0005=Cancel
0006=Welcome
0007=How are you today?
0008=Select Language

resource.fr-FR.txt: that contains the following French text.

French.jpg

resource.de-DE.txt: that contains the following German text.

German.jpg

resource.es-ES.txt: that contains the following Spanish text.

Spanish.jpg

resource.it-IT.txt: that contains the following Italian text.

Italian.jpg

resource.pt-PT.txt: that contains the following Portuguese text.

Pourtoguese.jpg

Now open the Visual Studio command prompt and run the resgen.exe with the .txt file as the parameter as shown in the image below.

Globalization1.gif

You will get a resource.en-US.resources file after running the Resgen for resource.en-US.txt. Similarly you will get six .resources files for each .txt files.

Creating a web application to use .resources files.

Now open the Visual Studio and open the new C# web application. Add a new a web page Default.aspx. Now open the Default.aspx in HTML mode and paste the following code below the @ page directive.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" >

<HTML>

 <HEAD>

  <title>Default</title>

  <meta name="GENERATOR" Content="Microsoft Visual Studio .NET 7.1">

  <meta name="CODE_LANGUAGE" Content="C#">

  <meta name="vs_defaultClientScript" content="JavaScript">

  <meta name="vs_targetSchema" content="http://schemas.microsoft.com/intellisense/ie5">

 </HEAD>

 <body MS_POSITIONING="GridLayout">

  <form id="Form1" method="post" runat="server">

   <asp:RadioButtonList id="rdoLanguage" style="Z-INDEX: 101; LEFT: 60px; POSITION: absolute; TOP: 24px"

    runat="server" AutoPostBack="True" Font-Names="Verdana" Font-Size="Smaller">

    <asp:ListItem Value="en-US" Selected="True">English</asp:ListItem>

    <asp:ListItem Value="fr-FR">French</asp:ListItem>

    <asp:ListItem Value="de-DE">German</asp:ListItem>

    <asp:ListItem Value="es-ES">Spanish</asp:ListItem>

    <asp:ListItem Value="it-IT">Italian</asp:ListItem>

    <asp:ListItem Value="pt-PT">Portuguese</asp:ListItem>

   </asp:RadioButtonList>

   <asp:Button id="Button1" style="Z-INDEX: 102; LEFT: 76px; POSITION: absolute; TOP: 180px" runat="server"

    Font-Names="Verdana" Width="68px" Height="24px" Text="-->" Font-Bold="True" Font-Size="8"></asp:Button>

  </form>

 </body>

</HTML>

See the values of List Item en-US for English, fr-FR for French, de-DE for German, es-ES for Spanish, it-IT for Italian and pt-PT for Portuguese. Resources Files will be read using these values, as you will see this later.

Now Switch to design mode, you will see the following output in design mode:

Globalization2.gif

Now in design mode click on the (-->) button. Default.aspx.cs will be opened. Write the following code in Button1_Click event:

private void Button1_Click(object sender, System.EventArgs e)

{

          Server.Transfer("Login.aspx");

}

Add a new Web Form to the project and rename it to Login.aspx. Now open the Login.aspx in HTML mode and paste the following code below the @ page directive.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" >

<HTML>

 <HEAD>

  <title>Login</title>

  <meta content="Microsoft Visual Studio .NET 7.1" name="GENERATOR">

  <meta content="C#" name="CODE_LANGUAGE">

  <meta content="JavaScript" name="vs_defaultClientScript">

  <meta content="http://schemas.microsoft.com/intellisense/ie5" name="vs_targetSchema">

 </HEAD>

 <body MS_POSITIONING="GridLayout">

  <form id="Form1" method="post" runat="server">

   <TABLE id="Table1" style="Z-INDEX: 107; LEFT: 8px; WIDTH: 455px; POSITION: absolute; TOP: 8px; HEIGHT: 48px"

    cellSpacing="1" cellPadding="1" width="455" border="0">

    <TR>

     <TD align="center" colspan="2"><asp:Label id="Label3" runat="server" Width="268px" Height="9px" Font-Names="Verdana" Font-Size="9pt"

       Font-Bold="True">User Login</asp:Label></TD>

    </TR>

    <TR>

     <TD align="right"><asp:Label id="Label1" runat="server" Width="272px" Height="8px" Font-Names="Verdana" Font-Size="8">Label</asp:Label></TD>

     <TD><asp:TextBox id="TextBox1" runat="server" Width="166px" Height="22px" Font-Names="Verdana" Font-Size="8"></asp:TextBox></TD>

    </TR>

    <TR>

     <TD align="right"><asp:Label id="Label2" runat="server" Width="268px" Height="9px" Font-Names="Verdana" Font-Size="8">Label</asp:Label></TD>

     <TD><asp:TextBox id="Textbox3" runat="server" sWidth="166px" Height="24px" Font-Names="Verdana" Font-Size="8"

       Width="164px"></asp:TextBox></TD>

    </TR>

    <TR>

     <TD align="right">

      <asp:Button id="Button1" runat="server" Text="Submit" Font-Names="Verdana" Font-Size="8"></asp:Button></TD>

     <TD>

      <asp:Button id="Button2" runat="server" Text="Cancel" Font-Names="Verdana" Font-Size="8"></asp:Button></TD>

    </TR>

   </TABLE>

  </form>

 </body>

</HTML>

Now Switch to design mode, you will see the following output in design mode:

Globalization3.gif

Now in design mode click on the submit button. Login.aspx.cs will be opened. Write the following code in the Button1_Click event:

private void Button1_Click(object sender, System.EventArgs e)

{

          Server.Transfer("Welcome.aspx");

}

Similarly for the cancel button, add the following code.

private void Button2_Click(object sender, System.EventArgs e)

{

          Server.Transfer("Default.aspx");

}

On the Page_Load event of the Login.aspx.cs add the following code:

private void Page_Load(object sender, System.EventArgs e)

{

          if(!Page.IsPostBack)

          {

                   //Retrive the Language from Default page

                   string strCulture = Request.Params["rdoLanguage"].ToString();

                   //Set the Current culuture to session variable

                   Session["SelectCulture"]= strCulture;

                   //create the culture based upon session culuture

                   CultureInfo objCI = new CultureInfo(strCulture);

                   Thread.CurrentThread.CurrentCulture = objCI;

                   Thread.CurrentThread.CurrentUICulture = objCI;

                   //Read the rsources files

                   String strResourcesPath= Server.MapPath("bin");

                   ResourceManager rm = ResourceManager.CreateFileBasedResourceManager("resource", strResourcesPath, null);

                   //Set the values read from resources to contorls

                   Label1.Text=rm.GetString("0001")+": ";

                   Label2.Text=rm.GetString("0002")+": ";

                   Label3.Text=rm.GetString("0003");

                   Button1.Text=rm.GetString("0004");

                   Button2.Text=rm.GetString("0005");

          }

}

Here you can see how we created the CulutureInfo object and passed the current selected culture string as a parameter to CulutureInfo. Then set the current page's culture to selected culture by using Thread.CurrentThread.CurrentCulture. Thread.CurrentThread.CurrentUICulture sets the current culture used by the Resource Manager to look up culture-specific resources at run time.

Add a new Web Form to the project and rename it to Welcome.aspx. Now open the welcome.aspx in HTML mode and paste the following code below the @ page directive.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" >

<HTML>

 <HEAD>

  <title>Welcome</title>

  <meta name="GENERATOR" Content="Microsoft Visual Studio .NET 7.1">

  <meta name="CODE_LANGUAGE" Content="C#">

  <meta name="vs_defaultClientScript" content="JavaScript">

  <meta name="vs_targetSchema" content="http://schemas.microsoft.com/intellisense/ie5">

 </HEAD>

 <body MS_POSITIONING="GridLayout">

  <form id="Form1" method="post" runat="server">

   <asp:Button id="Button1" style="Z-INDEX: 101; LEFT: 20px; POSITION: absolute; TOP: 36px" runat="server"

    Text="Select Another Language" Font-Size="8" Font-Names="Verdana" Width="152px"></asp:Button>

   <asp:Label id="Label1" style="Z-INDEX: 102; LEFT: 20px; POSITION: absolute; TOP: 12px" runat="server"

    Font-Size="8" Font-Names="Verdana" Width="392px">Label</asp:Label>

  </form>

 </body>

</HTML>

Now Switch to design mode, you will see the following output in design mode:

Globalization4.gif 

Now in design mode click on the (Select Another Language) button. Welcome.aspx.cs will be opened. Write the following code in Button1_Click event:

private void Button1_Click(object sender, System.EventArgs e)

{

          Server.Transfer("Default.aspx");

}

On the Page_Load event of the Welcome.aspx.cs add the following code:

private void Page_Load(object sender, System.EventArgs e)

{

          if(!Page.IsPostBack)

          {

                   string strCulture = Session["SelectCulture"].ToString();

                   CultureInfo objCI = new CultureInfo(strCulture);

                   Thread.CurrentThread.CurrentCulture = objCI;

                   Thread.CurrentThread.CurrentUICulture = objCI;

                   //Read the rsources files

                   String strResourcesPath= Server.MapPath("bin");

                   ResourceManager rm = ResourceManager.CreateFileBasedResourceManager("resource", strResourcesPath, null);

                   string strUserName = Request.Params["TextBox1"].ToString();

                   Label1.Text=rm.GetString("0006")+", " + strUserName + "! " + rm.GetString("0007");

                   Button1.Text=rm.GetString("0008");

          }

}

Now the coding part is complete. Copy the all six .resources files created in the first step to the bin directory of your web application.

In the Solution Explorer right-click the Default.aspx page and set it as the start up page. Now run the application. If everything is right in its place, you will see the following outut:

Globalization5.gif 

Select the language as English and click on the button. You will see the Login page as in the following:

Globalization6.gif

Enter Any User/Pass and click on the submit button. You will see the following output.

Globalization7.gif

Now click on Select Language and select French Language. You will see the Login page as follows:

Globalization8.gif

Enter Any User/Pass and click on the submit button. You will see the following output in French:

Globalization9.gif

Similarly you can check for German, Spanish, Italian and Portuguese for this example.

Conclusion

Here we have seen how System.Globalization helps us for localization of an application without modifying the application's source code. You can also explore System.Globalization for more languages and objects like RegionInfo, DateFormats and so on.


Similar Articles