To change the construction of this page so that it can be localized easily from resource files, open the page in Visual Studio and select Tools ➪ Generate Local Resource from the Visual
Trang 1Figure 30-8
When working with currencies, note that when you are using currencies on an ASP.NET page, you have
provided an automatic culture setting for the page as a whole (such as setting the culture in the@Page
directive) You must specify a specific culture for the currency that is the same in all cases unless you are
actually doing a currency conversion For instance, if you are specifying a U.S Dollar currency value on
your ASP.NET page, you do not want to specify that the culture of the currency is something else (for
example, the Euro) An exception would be if you actually performed a currency conversion and showed
the appropriate Euro value along with the culture specification of the currency Therefore, if you are
using an automatic culture setting on your ASP.NET page and you are not converting the currency, you
perform something similar to what is illustrated in Listing 30-11 for currency values
Listing 30-11: Reverting to a specific culture when displaying currencies
VB
Dim myNumber As Double = 5123456.00
Dim usCurr As CultureInfo = New CultureInfo("en-US")
Response.Write(myNumber.ToString("c", usCurr))
C#
double myNumber = 5123456.00;
CultureInfo usCurr = new CultureInfo("en-US");
Response.Write(myNumber.ToString("c", usCurr));
Understanding Differences in Sorting Strings
You have learned to translate textual values and alter the construction of the numbers, date/time values,
currencies, and more when you are globalizing an application You should also take note when applying
culture settings to some of the programmatic behaviors that you establish for values in your applications
One operation that can change based upon the culture setting applied is how NET sorts strings You
might think that all cultures sort strings in the same way (and generally they do), but sometimes
differ-ences exist in how sorting occurs To give you an example, Listing 30-12 shows you a sorting operation
occurring in the en-US culture
1394
Trang 2Listing 30-12: Working with sorting in different cultures
VB
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs)
System.Threading.Thread.CurrentThread.CurrentCulture = New CultureInfo("en-US")
Dim myList As List(Of String) = New List(Of String)
myList.Add("Washington D.C.")
myList.Add("Helsinki")
myList.Add("Moscow")
myList.Add("Warsaw")
myList.Add("Vienna")
myList.Add("Tokyo")
myList.Sort()
For Each item As String In myList
Response.Write(item.ToString() + "<br>")
Next
End Sub
C#
protected void Page_Load(object sender, EventArgs e)
{
System.Threading.Thread.CurrentThread.CurrentCulture = new CultureInfo("en-US");
List<string> myList = new List<string>();
myList.Add("Washington D.C.");
myList.Add("Helsinki");
myList.Add("Moscow");
myList.Add("Warsaw");
myList.Add("Vienna");
myList.Add("Tokyo");
myList.Sort();
foreach (string item in myList)
{
Response.Write(item.ToString() + "<br>");
}
}
For this example to work, you have to import theSystem.Collectionsand theSystem.Collections
.Genericnamespaces because this example makes use of theList(Of String)object
In this example, a generic list of capitals from various countries of the world is created in random order Then theSort()method of the genericList(Of String)object is invoked This sorting operation sorts the strings based upon how sorting is done for the defined culture in which the ASP.NET thread is
running Listing 30-12 shows the sorting as it is done for the en-US culture The result of this operation is presented in Figure 30-9
1395
Trang 3Figure 30-9
This is pretty much what you would expect Now, however, change the previous example from Listing
30-12 so that the culture is set to Finnish, as shown in Listing 30-13
Listing 30-13: Changing the culture to Finnish
VB
System.Threading.Thread.CurrentThread.CurrentCulture = New CultureInfo("fi-FI")
C#
System.Threading.Thread.CurrentThread.CurrentCulture = new CultureInfo("fi-FI");
If you run the same bit of code under the Finnish culture setting, you get the results presented in
Figure 30-10
Figure 30-10
1396
Trang 4If you examine the difference between the Finnish culture sorting done in Figure 30-10 and the U.S.
English culture sorting done in Figure 30-9, you see that the city of Vienna is in a different place in the
Finnish version This is because, in the Finnish language, there is no difference between the letter V and the letter W Because no difference exists, if you are sorting using the Finnish culture setting, thenVi
comes afterWaand thus Vienna comes last in the list of strings in the sorting operation
ASP.NET 3.5 Resource F iles
When you work with ASP.NET 3.5, all resources are handled by a resource file A resource file is an
XML-based file that has a.resxextension You can have Visual Studio 2008 help you construct this
file Resource files provide a set of items that are utilized by a specified culture In your ASP.NET 3.5
applications, you store resource files as either local resources or global resources The following sections look at how to use each type of resource
Making Use of Local Resources
You would be surprised how easily you can build an ASP.NET page so that it can be localized into other
languages Really, the only thing you need to do is build the ASP.NET page as you normally would and then use some built-in capabilities from Visual Studio 2008 to convert the page to a format that allows
you to plug in other languages easily
To see this in action, build a simple ASP.NET page as presented in Listing 30-14
Listing 30-14: Building the basic ASP.NET page to localize
<%@ Page Language="VB" %>
<script runat="server">
Protected Sub Button1_Click(ByVal sender As Object, _
ByVal e As System.EventArgs)
Label2.Text = TextBox1.Text End Sub
</script>
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title>Sample Page</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:Label ID="Label1" runat="server"
Text="What is your name?"></asp:Label><br />
<br />
<asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
<asp:Button ID="Button1" runat="server" Text="Submit Name" /><br />
<br />
<asp:Label ID="Label2" runat="server"></asp:Label>
</div>
</form>
</body>
</html>
1397
Trang 5As you can see, there is not much to this page It is composed of a couple of Label controls, as well as
TextBox and Button controls The end user enters her name into the text box, and then theLabel2server
control is populated with the inputted name and a simple greeting
The next step is what makes Visual Studio so great To change the construction of this page so that it can
be localized easily from resource files, open the page in Visual Studio and select Tools ➪ Generate Local
Resource from the Visual Studio menu Note that you can select this tool only when you are in the Design
view of your page It will not work in the split view or the code view of the page
Selecting the Generate Local Resource from the Tool menu option causes Visual Studio to create an
App_LocalResouces folder in your project if you already do not have one A.resxfile based upon this
ASP.NET page is then placed in the folder For instance, if you are working with theDefault.aspxpage,
the resource file is namedDefault.aspx.resx These changes are shown in Figure 30-11
If you right-click on the.resxfile and select View Code, notice that the.resxfile is nothing more than an
XML file with an associated schema at the beginning of the document The resource file that is generated
for you takes every possible property of every translatable control on the page and gives each item a key
value that can be referenced in your ASP.NET page If you look at the code of the page, notice that all
the text values that you placed in the page have been left in the page, but they have also been placed
inside the resource file You can see how Visual Studio changed the code of theDefault.aspxpage in
Listing 30-15
Listing 30-15: Looking at how Visual Studio altered the page code
<%@ Page Language="VB" Culture="auto" meta:resourcekey="PageResource1"
UICulture="auto" %>
<script runat="server">
Protected Sub Button1_Click(ByVal sender As Object, _
ByVal e As System.EventArgs)
Label2.Text = TextBox1.Text End Sub
</script>
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title>Sample Page</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:Label ID="Label1" runat="server" Text="What is your name?"
meta:resourcekey="Label1Resource1"></asp:Label><br />
<br />
<asp:TextBox ID="TextBox1" runat="server"
meta:resourcekey="TextBox1Resource1"></asp:TextBox>
<asp:Button ID="Button1"
runat="server" Text="Submit Name"
meta:resourcekey="Button1Resource1" /><br />
<br />
1398
Trang 6<asp:Label ID="Label2" runat="server"
meta:resourcekey="Label2Resource1"></asp:Label>
</div>
</form>
</body>
</html>
Figure 30-11 From this bit of code, you can see that theCultureandUICultureattributes have been added to the
@Pagedirective with a value ofauto, thus enabling this application to be localized Also, the attribute
meta:resourcekeyhas been added to each of the controls along with an associated value This is the
key from the.resxfile that was created on your behalf Double-clicking on theDefault.aspx.resxfile opens the resource file in the Resource Editor, which you will find is built into Visual Studio This new editor is presented in Figure 30-12
In the figure, note that a couple of properties from each of the server controls have been defined in
the resource file For instance, the Button server control has itsTextandToolTipproperties exposed
in this resource file, and the Visual Studio localization tool has pulled the defaultTextproperty value
from the control based on what you placed there Looking more closely at the Button server control
constructions in this file, you can see that both theTextandToolTipproperties have a defining
But-ton1Resource1value preceding the property name This key is used in the Button server control you
saw earlier
<asp:Button ID="Button1"
runat="server" Text="Submit Name"
meta:resourcekey="Button1Resource1" />
You can see that ameta:resourcekeyattribute has been added and, in this case, it references
But-ton1Resource1 All the properties using this key in the resource file (for example, theTextandToolTip
properties) are applied to this Button server control at runtime
1399
Trang 7Figure 30-12
Adding Another Language Resource File
Now that theDefault.aspx.resxfile is in place, this is a file for an invariant culture No culture is
assigned to this resource file If no culture can be determined, this resource file is then utilized To add
another resource file for theDefault.aspxpage that handles another language altogether, you copy
and paste theDefault.aspx.resxfile into the same App_LocalResources folder and rename the newly
copied file If you useDefault.aspx.fi-FI.resx, you give the following keys the following values to
make a Finnish language resource file
Button1Resource1.Text L¨ahet¨a Nimi
Label1Resource1.Text Mik¨a sinun nimi on?
PageResource1.Title N¨aytesivu
You want to create a custom resource in both resource files using the keyLabel2Answer The
Default.aspx.resxfile should have the following new key:
Label2Answer Hello
Now you can add the keyLabel2Answerto theDefault.aspx.fi-FI.resxfile as shown here:
Label2Answer Hei
1400
Trang 8You now have resources for specific controls and a resource that you can access later programmatically.
Finalizing the Building of the Default.aspx Page
Finalizing theDefault.aspxpage, you want to add aButton1_Clickevent so that when the end user
enters a name into the text box and clicks the Submit button, theLabel2server control provides a greeting
to him or her that is pulled from the local resource files When all is said and done, you should have a
Default.aspxpage that resembles the one in Listing 30-16
Listing 30-16: The final Default.aspx page
VB
<%@ Page Language="VB" Culture="auto" meta:resourcekey="PageResource1"
UICulture="auto" %>
<script runat="server">
Protected Sub Button1_Click(ByVal sender As Object, _
ByVal e As System.EventArgs)
Label2.Text = GetLocalResourceObject("Label2Answer").ToString() & _
" " & TextBox1.Text End Sub
</script>
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title>Sample Page</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:Label ID="Label1" runat="server" Text="What is your name?"
meta:resourcekey="Label1Resource1"></asp:Label><br />
<br />
<asp:TextBox ID="TextBox1" runat="server"
meta:resourcekey="TextBox1Resource1"></asp:TextBox>
<asp:Button ID="Button1"
runat="server" Text="Submit Name"
meta:resourcekey="Button1Resource1" OnClick="Button1_Click" /><br />
<br />
<asp:Label ID="Label2" runat="server"
meta:resourcekey="Label2Resource1"></asp:Label>
</div>
</form>
</body>
</html>
C#
<%@ Page Language="C#" Culture="auto" meta:resourcekey="PageResource1"
UICulture="auto" %>
<script runat="server">
protected void Button1_Click(object sender, EventArgs e)
Continued
1401
Trang 9Label2.Text = GetLocalResourceObject("Label2Answer").ToString() + " " + TextBox1.Text;
}
</script>
In addition to pulling local resources using themeta:resourcekeyattribute in the server controls on
the page to get at the exposed attributes, you can also get at any property value contained in the local
resource file by using theGetLocalResourceObject When usingGetLocalResourceObject, you simply
use the name of the key as a parameter as shown here:
GetLocalResourceObject("Label2Answer")
You could just as easily get at any of the controls property values from the resource file programmatically
using the same construct:
GetLocalResourceObject("Button1Resource1.Text")
With the code from Listing 30-16 in place and the resource files completed, you can run the page, entering
a name in the text box and then clicking the button to get a response, as illustrated in Figure 30-13
Figure 30-13
What happened behind the scenes that caused this page to be constructed in this manner? First, only
two resource files,Default.aspx.resxandDefault.aspx.fi-FI.resx, are available TheDefault
.aspx.resxresource file is the invariant culture resource file, whereas theDefault.aspx.fi-FI
.resxresource file is for a specific culture (fi-FI) Because I requested theDefault.aspxpage and my
browser is set to en-US as my preferred culture, ASP.NET found the local resources for theDefault.aspx
page From there, ASP.NET made a check for an en-US–specific version of theDefault.aspxpage
Because there is not a specific page for the en-US culture, ASP.NET made a check for an EN (neutral
culture) specific page Not finding a page for the EN neutral culture, ASP.NET was then forced to use the
invariant culture resource file ofDefault.aspx.resx, producing the page presented in Figure 30-13
Now, if you set your IE language preference as fi-FI and rerun theDefault.aspxpage, you see a Finnish
version of the page, as illustrated in Figure 30-14
1402
Trang 10Figure 30-14
In this case, having set my IE language preference to fi-FI, I am presented with this culture’s page instead
of the invariant culture page that was presented earlier ASP.NET found this specific culture through
use of theDefault.aspx.fi-FI.resxresource file
You can see that all the control properties that were translated and placed within the resource file are
utilized automatically by ASP.NET including the page title presented in the title bar of IE
Neutral Cultures Are Generally More Preferred
When you are working with the resource files from this example, note that one of the resources is for
a specific culture TheDefault.aspx.fi-FI.resxfile is for a specific culture — the Finnish language
as spoken in Finland Another option would be to make this file work not for a specific culture, but
instead for a neutral culture To accomplish this task, you simply name the fileDefault.aspx.FI.resx
instead In this example, it really does not make that much difference because no other countries speak
Finnish It would make sense for languages such as German, Spanish, or French These languages are spo-ken in multiple countries For instance, if you are going to have a Spanish version of theDefault.aspx
page, you could definitely build it for a specific culture, such asDefault.aspx.es-MX.resx This
con-struction is for the Spanish language as spoken in Mexico With this in place, if someone requests the
Default.aspxpage with the language setting of es-MX, that user is provided with the contents of this
resource file However, what if the requestor has a setting of es-ESHe will not get the Default.aspx.es-MX.resxresource file, but instead gets the invariant culture resource file ofDefault.aspx.resx If you
are going to make only a single translation into German, Spanish, or another language for your site or
any of your pages, you want to construct the resource files to be for neutral cultures rather than for
specific cultures
If you have the resource fileDefault.aspx.ES.resx, then it won’t matter if the end user’s preferred
setting is set to es-MX, es-ES, or even es-AR — the user gets the appropriate ES neutral culture version of the page
Making Use of Global Resources
Besides using only local resources that specifically deal with a particular page in your ASP.NET
appli-cation, you also have the option of creating global resources that can be used across multiple pages To
1403