
C# ПІДРУЧНИКИ / c# / Hungry Minds - ASP.NET Bible VB.NET & C#
.pdf
Table 20-2: Properties of the CultureInfo class
Property
CurrentUICulture
LCID
Description
Returns the CultureInfo instance that represents the current culture for the culture-specific resources.
Returns the culture identifier of the CultureInfo instance.
RegionInfo class
The RegionInfo class represents the information specific to a country/region. Unlike the CultureInfo class, the RegionInfo class information does not depend on the user's language or culture. The two-letter codes supported by the RegionInfo class to represent countries or regions are described in Table 20-3.
Table 20-3: Region names
Two-Letter Code |
|
Country/Region |
|
|
|
AE |
|
United Arab |
|
|
Emirates |
|
|
|
AU |
|
Australia |
|
|
|
AT |
|
Austria |
|
|
|
BG |
|
Bulgaria |
|
|
|
BR |
|
Brazil |
|
|
|
CA |
|
Canada |
|
|
|
CH |
|
Switzerland |
|
|
|
CZ |
|
Czech-Republic |
|
|
|
DE |
|
Germany |
|
|
|
EG |
|
Egypt |
|
|
|
ES |
|
Spain |
|
|
|
GB |
|
United Kingdom |
|
|
|
GR |
|
Greece |
|
|
|
HU |
|
Hungary |
|
|
|
IN |
|
India |
|
|
|
JP |
|
Japan |
|
|
|
LB |
|
Lebanon |
|
|
|
MX |
|
Mexico |
|
|
|
NZ |
|
New Zealand |
|
|
|
PK |
|
Pakistan |
|
|
|
RU |
|
Russia |
|
|
|
SG |
|
Singapore |

Table 20-3: Region names
|
Two-Letter Code |
|
|
Country/Region |
|
|
|
|
|
|
|
|
TR |
|
|
Turkey |
|
|
|
|
|
|
|
|
US |
|
|
United States |
|
|
|
|
|
|
|
|
ZA |
|
|
South Africa |
|
|
|
|
|
||
|
Note |
The RegionInfo names are not case-sensitive. To see the |
|
||
|
|
complete list of region names, refer to the .NET documentation. |
|
When you create an object of the RegionInfo class for a specific region, you need to pass the region name or the culture identifier as an argument to the RegionInfo constructor. Table 20-4 describes some of the properties of the RegionInfo class.
Table 20-4: Properties of the RegionInfo class
Property |
|
Description |
|
|
|
CurrentRegion |
|
Returns the |
|
|
|
|
|
RegionInfo |
|
|
instance |
|
|
that |
|
|
represents |
|
|
the |
|
|
country/regi |
|
|
on for the |
|
|
current |
|
|
thread. |
|
|
|
Name |
|
Returns the |
|
|
|
|
|
two-letter |
|
|
code for the |
|
|
country/regi |
|
|
on of the |
|
|
RegionInfo |
|
|
instance. |
|
|
|
EnglishName |
|
Returns the |
|
|
|
|
|
complete |
|
|
name of the |
|
|
country/regi |
|
|
on in |
|
|
English. |
|
|
|
DisplayName |
|
Returns the |
|
|
|
|
|
complete |
|
|
name of the |
|
|
country/regi |
|
|
on in the |
|
|
.NET |
|
|
Framework |
|
|
language. |
|
|
|
CurrencySymbol |
|
Returns the |
|
|
|
|
|
currency |
|
|
symbol |
|
|
associated |
|
|
with the |
|
|
country/regi |
|
|
on. |
|
|
|
IsMetric |
|
Indicates |
|
|
|

Table 20-4: Properties of the RegionInfo class
Property
Description
whether or not the metric system of measureme nt is used by the country/regi on.
Implementing the classes
After understanding the classes involved in creating international applications, you can now implement these classes. In the example discussed here, users are prompted for a culture name. When a user enters a culture name, such as en-US or de-DE, the page displays the name of the culture in English. Also, the native name is displayed. To implement this example, create a Visual Basic Web Application and create a SampleCulture.aspx file that has the following code:
<%@ Page Language="vb" AutoEventWireup="false" Codebehind=
"SampleCulture.aspx.vb" Inherits="ResourceApplication.WebForm1"%>
<%@Import Namespace="System.Globalization"%>
<%@Import Namespace="System.Threading"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
<HEAD>
<title></title>
<meta name="GENERATOR" content="Microsoft Visual Studio.NET 7.0">
<meta name="CODE_LANGUAGE" content="Visual Basic 7.0">
<meta name="vs_defaultClientScript" content="JavaScript">
<meta name="vs_targetSchema" content=
"http://schemas.microsoft.com/intellisense/ie5">
<script language="VB" runat="server">
Dim cult as CultureInfo
Sub Page_Load(ByVal sender as System.Object,ByVal args
as System.EventArgs) Handles MyBase.Load
If(IsPostBack) Then
Try
'Creating an instance of the CultureInfo class
by passing the value entered by a user in a text box
cult = new CultureInfo(InputCulture.Text)
Catch
cult = Nothing
End Try
Else
'initializing the CultureInfo instance to the 'current culture
cult = CultureInfo.CurrentCulture End If
End Sub
Sub DisplayButton_Click (ByVal sender as System.object,
ByVal e as System.EventArgs)
If Not( cult is nothing) then
'Setting the CurrentCulture property of the current 'thread to the instance of the CultureInfo class Thread.CurrentThread.CurrentCulture=cult
End If
'Set the text on a label to display the English name 'and native name of the culture. The Thread class is 'also used to display the English name and native name 'of the current culture.
CultureInfoLabel.Text= "The English name is: " & Cult. EnglishName.ToString & " (" & Thread.CurrentThread.CurrentCulture. EnglishName.ToString & " )" & " The native name is : " & cult.NativeName.
ToString & " (" & Thread.CurrentThread.CurrentCulture.NativeName.ToString & " )"
End Sub
</script>
</HEAD>
<body MS_POSITIONING="GridLayout">
<form id="Form1" method="post" runat="server"> <b><i>This is a culture demo</i></b>
<Br>
<Br>
<b>Enter the name of the culture</b>
<asp:TextBox id="InputCulture" style="Z-INDEX: 101; LEFT:
228px; POSITION: absolute; TOP: 53px" runat="server"></asp:TextBox> <asp:Button id="DisplayButton" onClick="DisplayButton_Click"
style="Z-INDEX: 102; LEFT: 407px; POSITION: absolute; TOP: 52px" runat="server" Text="Display"></asp:Button>
<asp:Label id="CultureInfoLabel" style="Z-INDEX: 103; LEFT: 20px; POSITION: absolute; TOP: 109px" runat="server">Culture Information</asp:Label>
</form>

</body>
</HTML>
When a user executes this code and enters "de-DE" in the text box and clicks the button, the English name and native name of the culture are displayed, as shown in Figure 20-1.
Figure 20-1: Sample output of the SampleCulture.aspx file
Using Resource Files
As mentioned earlier, a global ASP.NET application can be divided into two separate parts: data block and code block. These separate parts enable you to create localized versions of the applications without modifying the executable content. To produce the localized versions of a global ASP.NET application, you simply need to create localized versions of the data files. These files are called resource files, and must be persisted in a binary resource file format at run time. At run time, the appropriate resources are loaded depending on the culture settings provided by the browser.
When you make an application, it is a part of an assembly called the main assembly. If any change is made to this main assembly, you need to recompile the application. Because you might need to add the resources to provide support for more cultures, it is advisable to keep only the default set of resources in the main assembly. The other sets of resources can be kept in separate assemblies called satellite assemblies, which contain only resources. Therefore, changes made to these assemblies do not require you to recompile the application.
The first step to create the resource files is to identify the resources specific to different cultures and include them in files. For each culture, you need to include resources in a separate file. You can create a text file to do so. The text file stores a key/value pair for each resource. For example to store a value "Welcome" as a resource, you need to assign it to a key:
;A key/value pair
welcomeMessage = "Welcome"
In this sample code:
§The text following the semicolon represents a comment.
§welcomeMessage is a key.
§Welcome is the value assigned to the welcomeMessage key.
The keys are case-sensitive. While retrieving values from their
Note respective keys, if the proper case is not used, the values cannot be retrieved.
You can also include the identified resources in a ResX format, which is an XML format. In addition to the string resources, this format can also contain embedded objects. A typical ResX format is given as follows:
[Header]
[Entries: Strings]
key=value
[Entries: Objects]
The files containing resource entries must follow a specific naming convention. Otherwise, the system won't be able to find the resources at run time. For the default culture, the file should be named as Strings.txt or Strings.ResX. For any other culture, the filename must be of the form Strings.culture-name.txt or Strings.culture-name.ResX. For example, if the culture is "fr-FR", the file should be named as Strings.fr-FR.txt or Strings.fr-FR.ResX. Also, it is good practice to categorize these files in subdirectories under the application directory.
After you include all the resources in a file (text or ResX format), you need to convert it to a format that the .NET runtime can understand. To do so, you can use the Resource File Generator (ResGen.exe utility) utility. The syntax is shown as follows:
resgen [/compile] filename.extension [outputFilename.extension]
In this syntax:
§filename.extension represents a file that includes all the resource entries. The extension can be one of the following:
o.txt: Represents a text file to be converted to a RESOURCES or RESX file. This file can contain only string
resources.
o.resx: Represents an XML-based resource file to be converted to a RESOURCES or TXT file.
o.resources: Represents a resource file to be converted to a RESX or TXT file.
§outputFilename.extension represents the RESOURCES file that is
generated after conversion.
When converting from a TXT or RESX file, this parameter is optional. The TXT and RESX files are converted to files with the .resources extension. If you do not specify this parameter, the output file is named after the text file or the RESX file in the same directory where the input file exists.
When converting from a RESOURCES file, this parameter is mandatory.
§[/compile] is used to specify multiple RESX or TXT files to convert to a RESOURCES file in a single bulk operation. This is optional.
This utility can also be used to decompile. However, when you Note decompile the RESOURCES file, the comments are lost.
The .NET Framework provides a set of classes that work with the resource files to produce localized versions of a global ASP.NET application. The classes are encapsulated in the System.Resources namespace.
System.Resources namespace
The .NET Framework provides a class library that uses these resource files to retrieve resources for different languages at run time. The classes that allow developers to create, store, and manage various culture-specific resources used in an application are included in the System.Resources namespace. Some of the classes of this namespace are described as follows:
§ResourceManager: Represents a set of all the resources to be used in an application at the time of execution. This class provides many constructors that you can use to create its objects. The choice of the constructors depends on the need and the scenario in which you want to use resources. For example, when you need to retrieve resources from an assembly, you can use the constructor that takes three parameters: baseName,
Assembly, and Type.
§Dim rm as ResourceManager
rm = New ResourceManager(baseName, Assembly, Type)
In the preceding syntax, baseName represents the root name of the resource. Assembly represents the main assembly for the resources. Type represents the ResourceSet (covered next). If "Nothing" is used, the default run-time ResourceSet is used.
Note The satellite assemblies are compiled into DLLs and are referenced by the main assembly. However, you do not need any specific code for this reference. This is done by the ResourceManager.
On the other hand, if you need to retrieve resources from a directory instead of an assembly, you can use the CreateFileBasedResourceManager function of the ResourceManager class. This function takes three parameters: baseName, resourceDir, and type.
Dim rm as ResourceManager
rm = ResourceManager.CreateFileBasedResourceManager(baseName, resourceDir, type)
In the preceding syntax, baseName represents the root name of the resource, resourceDir represents the directory to search for the resources, and type represents the ResourceSet (covered next). If "Nothing" is used, the default runtime ResourceSet is used.
§ResourceSet: Represents the set of resources for a specific culture. The resources for every culture have an associated ResourceSet.
§ResourceWriter: Used to write the resources in a run-time binary resource file format. To create a resource file, you need to create a ResourceWriter object with an appropriate filename, such as CustomApplication.resource. Then, you need to call the AddResource (key, string) method to add each resource. Thus, to add N resources, you need to call the AddResource method N times. Finally, you need to call WriteFile to write the
resources. To use the resources, you can then create an object of ResourceManager and call the getString(key) or getString(key, culture).
Instead of the ResourceWriter class, you can use the ResGen utility to Note create resources in a run-time binary resource file format.
§ResourceReader: Used to read resources in a run-time binary resource file format. To create a ResourceReader, you need to pass the filename in the constructor.
Creating a resource-aware application
Let us now create an ASP.NET application that is aware of resources. Here, you'll create resources for two cultures, en-US and fr-FR. The application loads the resources depending on the selected culture while the application runs. Not only this, the application displays the localized information in a highly graphic manner. An output of this application is displayed in Figure 20-2. Notice that the output displays the localized information in French.

Figure 20-2: Sample output of a resource-aware application
To create this application, complete the following steps:
1.Create a directory named ResourceApplication. This directory is the application's main directory. Create a virtual directory in the Default Web site on your Web server. Specify the alias as ResourceDemo and the path of the content as the path of the ResourceApplication directory.
2.In the ResourceApplication directory, create a subdirectory called Resources. This directory will include all the resource files.
3.Create a default Strings.txt file in the Resources directory. This file contains the resources as key/value pairs. The code is shown as follows:
4.[strings]
5.;prompts
6.
7.NameStr = What is your name?
8.AgeStr = What is your age?
9.
10. OutputStr = Your information is:
11.
12.;outputs
13.OuputNameStr = Name:
OutputAgeStr = Age:
14.Convert this text file to a RESOURCES file. To do so, use the ResGen utility with the following:
ResGen Strings.txt
15.Create the resource files for other cultures that your system supports. For example, to create a resource file for the culture fr-FR, create the Strings.fr-FR.txt file that includes all the resources. Then, use the ResGen utility to convert the file to the Strings.fr-FR.resources file. The sample code for the Strings.fr-FR.txt file is given as follows:
16.[strings]
17.;prompts
18.
19.NameStr = Comment vous appellez-vous?
20.AgeStr = Quel age avez-vous?
21.
22. OutputStr = Votre information:
23.
24.;outputs
25.OuputNameStr = Nom:
outputAgeStr = Age:
Note You can also create the resource files for other cultures later to add support for more cultures, without recompiling the application.
26.In the application's main directory, ResourceApplication, create the ResourceSample.aspx file. The code is given as follows:
27.<%@ Import Namespace="System" %>
28.<%@ Import Namespace="System.IO" %>
29.<%@Import Namespace="System.Globalization"%>
30.<%@ Import Namespace="System.Resources" %>
31.<%@Import Namespace="System.Th reading"%>
32.
33. <script runat="Server" Language="VB" >
34.
35.'Declaring shared public objects
36.Public Shared rm As ResourceManager
37.Public Shared cinfo As CultureInfo
38.
39.Sub Page_Init(ByVal sender As System.Object,
40.ByVal args As System.EventArgs) Handles MyBase.Init
41.
42.'Create an instance of the ResourceManager class
43.rm = ResourceManager.CreateFileBasedResourceManager("strin gs",
44.Server.MapPath("resources") + Path.DirectorySeparatorChar, _
45.Nothing)
46.
47.CultureList.Items.Clear()
48.'Adding the names of cultures to the drop down list
49.CultureList.Items.Add("Select your language")
50.CultureList.Items.Add("fr-FR")
51.CultureList.Items.Add("en-US")
52.
53. |
End Sub |
54.
55.Sub Proceed_Click(src As Object, E As EventArgs)
56.
57.'Create an instance of the CultureInfo class
58.cinfo = New CultureInfo(CultureList.SelectedItem.Text)
59.
60.'Setting text on the Name label from the resource file
61.EnterNamelabel.Text = rm.GetString("NameStr",
cinfo)
62.
63.
64.'Setting the Visible property of the Name label to true
65.EnterNamelabel.Visible = true
66.
67.'Disable the Culture label, Culture list, and the
68.'Proceed button
69.Culturelabel.Enabled = false
70.CultureList.Enabled = false
71.Proceed.Enabled = false
72.
73.'Setting the Visible property of the Name Next button
74.'and Name text box to true so that the user can enter
75.'his/her name
76.NameNextButton.Visible = true
77.EnterNametextbox.Visible = true
78.EnterNametextbox.Text = ""
79.End Sub
80.
81. Sub NameNextButton_Click(src As Object, E As
EventArgs)
82.
83.'setting text on the Age label from the resource file
84.'and setting its Visible property to true
85.EnterAgelabel.Text = rm.GetString("AgeStr", cinfo)
86.EnterAgelabel.Visible = true
87.
88.'Disabling the Name label, Name text box, and the
Name
89.'Next button
90.EnterNamelabel.Enabled = false
91.EnterNametextbox.Enabled = false
92.NameNextButton.Enabled = false
93.
94.'Setting the Visible property of the Age text box to
95.'true so that a user can enter his/her age