See Joel Program

January 2, 2008

Using Localization in ASP.NET AJAX (Part 1) : Using Localization in ASP.NET

Filed under: AJAX, ASP.NET AJAX — Tags: , , , — Joel Rumerman @ 9:29 pm

I’ve been learning about Localization in ASP.NET AJAX and I’m not a big fan of the resources that are currently available so I thought I would write down my thoughts in the hopes that other people might find them useful. It looks like this will be a three part series on Localization in ASP.NET Ajax and this first entry will be about localization in ASP.NET without the Ajax portion.

Part 1: How to localize an application in ASP.NET

Edit: After writing this post, I found an excellent resource on the basics of localization in ASP.NET. Rick Strahl, a resource for many in the .NET Community and co-publisher of CoDe magazine, wrote an excellent article a while back on Localization: Introduction to Localization in ASP.NET 2.0. While I’m glad that I went through the process of writing this article and I believe that some of my insights come from a different angle than Rick’s, if you’re just starting out with Localization, his article is a must read.

Another decent resource is ASP.NET 2.0 Localization Features: A Fresh Approach to Localizing Web Applications

Part 2: How to localize JavaScript using static JavaScript files

Part 3: How to localize ASP.NET AJAX using embedded resources

What is Localization?

Building your application to support multiple cultures and languages is called localization. Localization includes not only displaying information to the user in the language they speak or read, but also displaying information in their culture (i.e. Spanish, Mexico instead of Spanish, Spain).

In the programming world, a culture is defined by a code. For example, en-us stands for English language, United States culture, en-gb stands for English language, Great Britain culture, and de-au stands for German, Austrian culture.

There are also general language codes that don’t specify a culture, en for English, es for Spanish, it for Italian, etc.

When we specify a culture that our application should run under, we are telling the application to display information with that culture in mind. Unfortunately for us developers, we have to help the application along and tell it what we want we’d like localized. The process of instructing our application what should change when we specify a different culture is called localizing our application.

Localizing our ASP.NET Application

One of the great things about ASP.NET is its ability to support localization without too much trouble.

The key steps of localizing our application are

  1. Determining what needs to be localized (i.e. strings, pictures, currency, dates, and numbers)
  2. Setting up your application to localize values when they’re displayed to the user (i.e. using resource files and string formatting),
  3. Getting your application to figure out which culture to apply (implicitly or explicitly setting the current thread’s culture).

Determining What Needs to be Localized

When determining what needs to be localized you need to consider the different types of information that your application provides because almost all of it will need to be localized if you are going to fully support another language and culture. The basics of what needs to be localized are currencies, dates, numbers, strings, and graphics. If you think about it, this covers the majority of your application’s user interface. The other thing that you’ll need to look out for are layout issues. English words tend to be short when compared to say German. If you only allow for 15 characters of space before your line will wrap, the German will look really weird.

Once you’ve determined what in your application needs to change in appearance when the application is running under different cultures you can move onto the next step.

Localizing Displayed Values

Truthfully, this is where 90% of the work in localization takes place. In this step, you need to actually write your code to use localized values. We can break down the things that are localized into two categories: those that ASP.NET will automatically localize for us and those that we have to manually localize.

Automatic Localization

What ASP.NET can automatically localize are currencies, dates, and numbers. Let’s dive into that a bit deeper by looking at how a date is automatically displayed differently when our application is running in two different cultures.

When I create a new date, I can display it using the ToString() method attached to the Date object. Using the ToString() method automatically displays the date in the current culture’s default format. As you probably know, assuming you’re a U.S. citizen, the U.S. writes its dates our Month/Day/Year (unless you’re military). A lot of the world, including the French, write their dates out Day/Month/Year. If I were running my application under the French culture, I would expect that the date be displayed Day/Month/Year. Lucky for us, ASP.NET takes care of this for us.

A simple page that will display two strings

image

The code behind that will output the date in the two different formats.

image

Finally, the outputted display

image

By setting the culture, I’ve altered how the date automatically displays itself when outputted. As you can see, the time formatting also changes with the French being in 24hr time.

This idea continues through numbers, dates, and currencies. Whenever you use the ToString or String.format methods to output a string from a integer, float, double, date, long, etc. object, ASP.NET internally uses the current culture’s formatting information to alter the display for that culture. (Note: You can override the default culture and by specifying a format provider in the ToString or String.format methods.)

Manual Localization

What ASP.NET doesn’t automatically localize we must do manually. The types of objects we must manually localize are strings, images, files, icons, etc. Things where ASP.NET cannot automatically determine what the output should be. This means that we need to help ASP.NET along. We help ASP.NET along using resource (resx) files.

There are two different types of resource files:

  1. Master Resource File
  2. Culture Specific Resource Files

Master Resource File

The Master Resource File represents the default (or invariant) culture. This file contains the master list of all things that you are going to manually localize and their default values. A common name for this file is Resource.resx and it does not specify a culture in its name such as Resource.it.resx. (The first part of the name, Resource, is important because it becomes the class name of the compiled resource. As we’ll see if we want to override the default values in a culture specific resource file we must use the same file name.)

Culture Specific Resource Files

Culture Specific Resource files files contain culture specific information. For every culture that we want to support we create a resource file and name it appropriately. For instance, if want to support the Spanish, Mexico culture (es-MX), we need to have a resource file named Resource.es-mx.resx. If we intend to support Italian, we need to have a file named Resource.it.resx. (Notice it has the same first part of the name as our master resource file.)

These resource files contain the overrides for the master resource file. For instance, if we had the resource named “MyText” in the master resource file with the value “Hello World!” and we wanted to override it in Italian resource file, we’d have the same resource named “MyText” but would set its value to “Ciao Mondo!” instead.

Now that you understand the two different types of resource files, let’s look at how they work in ASP.NET

Creating Resource Files in a Website Project

Depending on how we want to use the localized information, resource files can be stored in various locations. For the purposes of this example let’s assume we’re using a website project. The first thing we do is add a special ASP.NET folder called App_GlobalResources to our website application. Once we do that we create the master resource file and add it to App_GlobalResources folder.

image

We then need to define our resources and their default values. We open up the Resource editor by double clicking on the resource file and add our resources to it.

image

In the background, Visual Studio is building an XML document that contains our resourced values.

image

This XML is then converted into a class that we can access in a couple of ways. The easiest way to see how to access the resource is through code behind so that’s create a page and assign our resources to a couple of labels through code behind. (You can also use a databinding expression.)

The HTML

image

The Code behind

image

Note: Accessing resources through the strongly typed auto-generated classes as we do in this brief example performs poorly. Accessing it through a Global Resource Object or implicit or explicit tags performs better. This article explains why it performs poorly.

When we run this we see that our labels are populated with the resources.

image

Pretty straight forward so far, eh?

But now we want to support the Italian general culture. First, we need to create an Italian resource file and add it to our App_GlobalResources directory.

image

Now we need to override our two resources so they have Italian values. Using Babel Fish to figure out the translations we end up with a resource file that looks like

image

Now in a real world application we’d wait for an Italian user to come along and request our page, but since we’re testing this, we’ll force our code to run under the Italian culture (we’ll go over this in detail in the next section).

image

Now when our page runs we see the Italian text instead of the English.

image

To demonstrate one final point in this section, let’s add one more culture, es-MX to our application.

image

In our es-mx resource file, we’ll only override the MyText resource and not the MyOtherText resource.

image

Updating our code behind so that it uses the es-MX culture instead of the Italian.

image

And then running the application

image

Notice how it used the value from the es-mx resource file for the Hello World portion of the page, but it defaulted to the invariant culture file for the Goodbye World portion. It did this because we didn’t override the master file’s MyOtherText resource. What actually happens here is that ASP.NET combines the valid resource files for the current culture, giving higher precedence to the most specific culture file’s value.

In reality, a culture can have three resource files working at once. The invariant, the general language, and the culture specific language. We’ve talked about the invariant resource file and the culture specific language resource file, but we haven’t talked about the general language file. General culture files are those that leave off the culture portion of the code (i.e. MX) and just reflect the language: Resources.es.resx or Resources.en.resx. We can reduce the number of resources we have to override by using this hierarchy of resource files to our advantage and only overriding those that differ between each level.

Figuring Out Which Culture to Apply

In .NET, the culture is attached to the current thread. You can access it through

System.Threading.Thread.CurrentThread.CurrentCulture and System.Threading.Thread.CurrentThread.CurrentUICulture.

In the case that you want to implicitly set the current culture, you really don’t do anything. In this case, the browser sends back the languages it accepts, for example en-us (English U.S.), es-MX (Spanish, Mexico), or it (Italian, general), and the ASP.NET runtime sets the current thread’s culture automatically based upon these values. (The browser sends back these values based upon your browser’s language settings, which you can change in the various browsers.)

In the case that you want to explicitly set the current culture, you have to override the implicit settings.

If wanted to set the current culture to es-MX, we would execute code in the page’s InitializeCulture method that does this.

Set Mexican Culture

Once this is done, our page would be running under the Spanish, Mexico culture for both resources and formatting of numbers, currencies, and dates. If you only wanted to access the localized resources, but leave the dates, currencies, and numbers displayed using the current culture, you would leave off the CurrentCulture assignment.

CurrentUICulture vs. CurrentCulture is a little bit confusing and I think the best explanation can be found here.

Well, that concludes are somewhat cursory look at localizing an ASP.NET application. The next posts will focus on using resources with ASP.NET Ajax.

2 Comments »

  1. […] @ 9:38 pm A while back I promised a three-part series on ASP.NET AJAX Localization. I wrote Part 1, but wasn’t entirely happy with the way it turned out; primarily because I was still learning […]

    Pingback by ASP.NET AJAX Localization Slides and Code « See Joel Program — March 6, 2008 @ 9:38 pm

  2. Joel,

    I wrote an article on this subject for MSDN Magazine last year. You can read it at http://msdn.microsoft.com/msdnmag/issues/08/01/InternationalizingASPNETAJAX/default.aspx. Also I have a book on internationalization imaginatively entitled “.NET Internationalization” published by Addison-Wesley. On the book’s site (http://www.dotneti18n.com) you can download a utility I wrote that cracks the ScriptResource and WebResource handler references so you can see exactly how this process works in ASP.NET AJAX.

    Guy

    Comment by Guy Smith-Ferrier — March 27, 2008 @ 12:30 pm


RSS feed for comments on this post. TrackBack URI

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Blog at WordPress.com.

%d bloggers like this: