When you think ASP, think...
Recent Articles xml
All Articles
ASP.NET Articles
Related Web Technologies
User Tips!
Coding Tips
spgif spgif

Book Reviews
Sample Chapters
JavaScript Tutorials
MSDN Communities Hub
Official Docs
Stump the SQL Guru!
Web Hosts
Author an Article
spgif spgif

ASP ASP.NET ASP FAQs Feedback topnav-right
Print this Page!
Published: Wednesday, March 3, 2004

Globalizing ASP.NET Applications With Non-Standard Languages

By Jason Salas


Have you ever wanted to use a language, character set or encoding type not inherently supported in the .NET Framework in your web applications? Perhaps you've got a comical interest to display your content in Pig Latin, Ewok, GeekSpeak, or some unique dialect you and your friends developed between each other. Or, maybe you've got a more legitimate business problem to solve, like displaying content for a certain race of people whose native tongue isn't recognized by the International Standards Organization (ISO). If you've ever been in any of the above situations, you'll want to read on. In this article, I'm going to show you how to easily extend the current functionality of the .NET Framework to support rare, uncommon or even completely new languages for use in your ASP.NET projects.

- continued -

Programming With New/Non-Standard Languages

I came across a problem recently when I wanted to have certain sections of my company's Web site display information in languages other than English. Doing so provides a rich level of customer service and allows us to interact with people who might not use the Internet otherwise for information, or prefer to receive information in a manner more convenient to them.

The problem was that that the languages I was looking to support – Chamorro (Guam's native language), and Tagalog (the dominant dialect used in the Philippines) aren't recognized by the ISO. At first glace, it appears that using them in the .NET Framework is impossible, because an overloaded constructor for the CultureInfo class, found in the System.Globalization namespace, requires a string argument specifying an ISO-recognized culture. However, not all is lost. I'm fortunate that both Chamorro and Tagalog are heavily influenced by Spanish, so that date-time formatting strongly resembles that language. So, in creating new cultures, we're going to inherit from Spanish as a base reference.

Localization Does Not Mean Automatic Translation

Before we get to the code, let's dispel a rumor that I'm accosted with at nearly every talk I give about globalizing applications with .NET. Not surprisingly, many people jump to the conclusion when first hearing about .NET's globalization capabilities that .NET apps will be able to take content in one language and automatically translate it to another. While this would be an amazing feature to have available, it's sadly not available at the moment. For that reason, I'm going to do in this article what I do in technical presentations I give on ASP.NET: avoid any further use of the word "translate."

To display content in foreign languages in this example, I'm going to tap into resource files. Since the information in these resource files are pre-populated with information, they're best used for static content areas like headers, footers or greetings. However, services like AltaVista's Babel Fish Translation Service certainly make it easy to translate dialogue from one language to another (oops…I'm supposed to be avoiding that word, aren't I?)

Get to the Code, Already!

OK, OK... onto the code! I'm going to borrow from an excellent example from Francois Liger on creating custom cultures for use in applications. We only need to define a custom type to create one or more cultures, setup some resource files, and we're done! For purposes of simplicity, I'm coding the entire page and custom class inline within the same page. Of course, in a practical localized application, you'd probably want the settings available to more than just a single page, so the class would be stored in its own code file and stored as an assembly. Also, I'm going to create a file-based resource manager instance, which in a more realistic environment would take a backseat to using satellite assemblies.

First, we import the necessary namespaces to make use of the methods and properties we'll call and set. These @Import directives are added to the ASP.NET Web page, since I am using the server-side script block approach for this example. If you were using Visual Studio .NET's code-behind model, you'd use using (C#) or Imports in your code-behind class file:

<%@ import namespace="System.Globalization" %>
<%@ import namespace="System.Threading" %>
<%@ import namespace="System.Resources" %>
<%@ import namespace="System.IO" %>

Next, we create a custom class, CustomGuamCulture class, inheriting from CultureInfo and overriding some of the base class's public properties. Pay particular importance to how the base Parent property is overridden by creating a new CultureInfo instance, which is the parent culture specified in the overloaded class constructor. This ensures we derive from an existing culture, and therefore, we can use the base class's number and date formatting.

public override CultureInfo Parent
{ get { return new CultureInfo(this._parent); } }

public CustomGuamCulture(string parent, string customLanguageCode,string formalName) : base(parent)
    this._parent = parent;
    this._name = string.Format("{0}-{1}", parent, customLanguageCode);
    this._description = string.Format("Custom culture ({0})", formalName);

One thing to note is that because the constructor of CustomGuamCulture takes an existing culture as its parent, the .txt files containing the multilingual content need to be named so that they reference the parent and the custom culture:

customCulture.txt (the neutral culture file)

Then, just use the ResGen tool to make the .resources files using, and you're all set!

resgen customCulture.txt 
resgen customCulture.es-ES-gu-CH.txt
resgen customCulture.es-ES-pi-TA.txt

Now, we've got all we need to use our custom languages in an ASP.NET Web page! Just add the logic into the page's Load event. Notice how I use a C# switch statement to figure out what value the user selected within a RadioButtonList control I placed declaratively on the page: if the value of the RadioButtonList is either Chamorro or Tagalog, the CultureInfo variable ci uses our custom class. Any other selection would trigger the default action, which is to use the normal CultureInfo class.

protected void Page_Load(object sender, EventArgs e)
    CultureInfo ci;
    switch (Radiobuttonlist1.SelectedValue.ToString())
        // if the user selected either CHAMORRO or TAGALOG as their preference, 
        //load the resource file for that language
        case "gu-CH" :
        case "pi-TA" :
            ci = new CustomGuamCulture("es-ES", 
        default :
            ci = new CultureInfo(Radiobuttonlist1.SelectedValue.ToString());
    Thread.CurrentThread.CurrentCulture = ci;
    Thread.CurrentThread.CurrentUICulture = ci;

    ResourceManager rm = ResourceManager.CreateFileBasedResourceManager("resource", 
                   Server.MapPath("resources") + Path.DirectorySeparatorChar, null);

    lblGreeting.Text = rm.GetString("Greeting");
    lblNames.Text = rm.GetString("FirstName") + " " + rm.GetString("LastName");
    lblDate.Text = DateTime.Now.ToString("D");
    lblCulture.Text = "Using culture: " + ci.EnglishName;

The page-level CurrentCulture and CurrentUICulture properties for the currently-executing thread are set to the instance of ci. We also create a ResourceManager by mapping to the /resources folder within the web app and then write out the value of the appropriate resource file to a series of Label controls. The complete code sample can be downloaded from a link at the end of this article.

The following three images show screenshots of the ASP.NET Web page in action. Note that as the culture choice is changed, the format of the date/time and the messages are changed to reflect the selected culture. The first screenshot shows the output when the English culture is selected, the second shows the French culture, and the third and final screenshot shows the output when using our custom Tagalog culture.

The English culture has been selected.

The French culture has been selected.

The Tagalog culture has been selected.

Further Extensions

Of course, this is only a simple demonstration of how a developer can extend globalization. Both languages demonstrated derive from Roman, and as such, use an alphabet common to English, Italian, German, and other languages. If you were using a language with an entirely different character set, like Chinese, Japanese, Korean, Cyrillic or Arabic (or, you made up your own language), you'd have encoding and unique character concerns to deal with.

In fact, Christian Nagel has a fun example on how to do this for a language not deriving from anything the ISO provides by default - Klingon (see http://www.christiannagel.com/My+Downloads/71.aspx). But, it is possible. And maybe, just maybe, one day, the .NET Framework will provide the ultimate goal of automated translation. Dang... did it again.


I hope you've found this article interesting, in demonstrating that extending the current collection of languages provided by .NET's globalization capabilities provides makes for a whole new world of opportunity. And in doing so, it's really quite easy. Hopefully, this will lead to other interesting and creative projects for you in your own programming. I'd love to hear about them, drop me a line at jason@kuam.com and share your work.

Happy Programming!

  • By Jason Salas


  • Download the Resource Files and Complete Code
  • Links Mentioned in this Article:

  • Christian Nagel: Building International Applications with the .NET Framework
  • Francois Liger: Creating a Custom Culture with the .NET Framework
  • MSDN: System.Globalization.CultureInfo Class
  • AltaVista's Babel Fish Translation Service
  • Other, Recommended Links

  • Internationalize Your ASP.NET Applications
  • Resources in ASP.NET Applications
  • Working with Resource Files
  • ASP.NET Localization
  • Globalization Architecture for ASP.NET

  • ASP.NET [1.x] [2.0] | ASPMessageboard.com | ASPFAQs.com | Advertise | Feedback | Author an Article