Click here to Skip to main content
15,888,293 members
Articles / Web Development / ASP.NET

Page Localization

Rate me:
Please Sign up or sign in to vote.
4.00/5 (5 votes)
12 Feb 2010CPOL4 min read 19.9K   301   8  
A primer on using Global and Local resource files in your web applications.

Introduction

Sometimes, wading through the Microsoft information swimming pool can flood you with more options than you bargained for. The purpose of this article is to provide one very simple example of how to localize your ASP.NET website using global and local resource files. While there are many framework approaches available to localize a website, this is perhaps the most common, and utilizes the built-in infrastructure in .NET to its greatest extent.

Background

After so many years of funneling the Microsoft mud into my tiny brain, I tend not to memorize much anymore, and instead rely on focusing on where to find what I need. I decided to go ahead and write myself an example program for future reference and some notes so that I don't have to dig again the next time I do this a year or so from now. Here, I'll share that example with you, and hope it serves to cut to the point very quickly and easily for you when you need a quick reference.

Using the Code

The following code is really only a part of what needs to be done. The main trick is creating the correct directories, creating the correctly named resource files, and then using the code-behind to convince your site to use the correct set of resource files. This code assumes you have created the proper directories in your project.

Specifically, you need to have the following folders:

  • App_GlobalResources
  • Right click your project and select "Add ASP.NET Folder", select "App_GlobalResources"

  • App_LocalResources
  • Repeat the same steps, but pick App_LocalResources.

For the Global Resources, it really doesn't matter what you name your resource file. What matters is the filename extension you use for the additional languages. Global resources are retrieved manually in your code-behind.

Create the following global resources files in your global resources folder. (Note the very simple syntax to delineate the Spanish language resource file.)

  • GlobalResources.resx
  • GlobalResources.es.resx

For Local Resources, it very much matters what you call your files. Each file you place in here should correspond 1:1 with an ASPX page you are localizing. For each separate "project" in your solution, you can and should have a separate resource folder and local resource file in it! Local resources are automatically used. No code is needed. In this case, here is what you would use for your Default.aspx page if you wanted an English and Spanish local resource file:

  • Default.aspx.es.resx
  • Default.aspx.resx

You would probably only want to place resources in the global resource file if you plan on using it in multiple pages. For strings used only on one page, the best practice is to use a local resource file. It's also the easiest since it's automatic, provided you name everything with the correct extensions and put them in the right place.

In your ASPX page, as you can see below, we use a special tag called "mega:resourcekey" to identify the resource in our local resources file. This resource will be filled in automatically. No manual code is needed. The name of the resource key you use must match up with the name of the resource that you add in your local resource file.

ASP.NET
<localize id="Label1" meta:resourcekey="locLabel1Resource" runat="server">
<localize id="Label1" meta:resourcekey="locLabel1Resource" runat="server" >

Let's also create a simple label that we will set manually in our code-behind using the global resources.

ASP.NET
<label id="GlobalLabel" runat="server" text="Global Resource Text">

Here are a couple examples of manually retrieving global and local resources:

C#
protected void Page_Load(object sender, EventArgs e)
{
    // Here is how we can manually set our label's text using a global resource.
    // Notice the easy syntax for fetching a global resource.
    GlobalLabel.Text = Resources.GlobalResources.glbLabel1Resource;

    // Here is how you can grab a local resource manually..
    // I'm not doing anything with it,
    // but it shows how you can retrieve it in code if you ever want to.
    // Sometimes you manipulate local resources
    // in code and need to pull them manually,
    // and this is how you do it.
    string sometext = (string)GetLocalResourceObject("locLabel1Resource.Text");
}

In order for .NET to automatically use local resources, you have to tell it what culture you wish to use. Setting the current web pages culture is done in the InitializeCulture() event of a page. This event occurs early in the page lifecycle, so you can't access values in the controls on your page using normal .NET syntax. In this case, we are looking at a combo-box on our main page that has a list of languages the user can select. In order to get that selection, we have to manually look at the form's field collection to get the selected visible value from the combo-box. It's important to note that the CurrentCulture of the current thread controls things such as the displayed currency, whereas localized text is controlled by the thread's CurrentUICulture value. Generally, just set both unless of course you want to do something like display U.S. Dollars in China.

C#
protected override void InitializeCulture()
{
    if (Request.Form["LanguageSelector"] != null)
    {
        SetLanguage(Request.Form["LanguageSelector"]);
    }
}

private void SetLanguage(string selectedLanguage)
{
    // This is how you should set it.
    UICulture = selectedLanguage; // Controls things like displayed Currency
    Culture = selectedLanguage;   // Controls displayed text

    // This is an alternate method of doing
    // the same thing as above, so don't do both.
    Thread.CurrentThread.CurrentCulture = 
      CultureInfo.CreateSpecificCulture(selectedLanguage);  
    Thread.CurrentThread.CurrentUICulture = 
           new CultureInfo(selectedLanguage);

    base.InitializeCulture();
}

Points of Interest

I've seen quiet a few creative methods for localizing a web page. Some intercept rendering events down in the bowels of the framework and override text values using elaborate database driven schemes. These allow for great flexibility, but the framework doesn't really go very far in providing a nice abstracted interface to let you do what you need. I think that's a failing in the framework, as database driven localization is quite common and, unfortunately for our industry, quite diverse because there is no standard. However, it's still doable, and a powerful technique. For this example however, we've approached it using the standard framework file-based methodology which is very effective.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior) Isagenix International Inc.
United States United States
I'm an old fart living on the bleeding edge of technology. Started off as a EE out of college and got into embedded programming back in the 80's for a while and then did my share of PC programming starting in the DOS days all the way up to using the latest stuff in .NET 4.0. I've been programming on and off for about 25 years now and continue to love figuring out problems and seeing things work and understanding the root causes for why we solve the same problems every year. Did my fair share of PM'ing and Management over the years, but mostly stick with programming because frankly, marketing people scare the heck out of me (much like clowns do).

I'm a huge advocate for solving systematic development problems with improved processes as opposed to re-factoring and/or throwing new technology at a problem and hoping for the best because some inexperienced kid tells us it's awesome. I'm the "old guy" who knows best because I've done everything a crap load of times using every new method out there and so I do know best.

My sincere hope is that some day our industry will stop re-inventing the same "wheels" in order to make a short sighted buck, and move towards a model of true innovation where software transcends the current fixed patterns we re-implement each and every day in an endless cycle. Is there life out there among the drones?

I enjoy fishing, camping, SCI-FI MMO's, Aquariums, shooting lizards with a BB-Gun and of course, eating food so spicy that it strips the lining off your colon.

Comments and Discussions

 
-- There are no messages in this forum --