I posted about this topic last week and after a few suggestions and considerations I’ve reworked some of the code and text in this topic .  04/10/2004

 

I’ve been working with Kevin on a bunch of localization issues related to Mere Mortals Framework over the last few weeks and here is one useful tip that once again demonstrates how nice and easy some things can be when using ASP. Net.

 

One of the things we need to do when localizing an app is also deal with the various display formats for numbers, dates etc. In .Net switching this format is nothing short of trivial by simply setting the current thread to a given Locale. If you’re using any of the .Net formatting methods such as string.Format() .Net will take care of all of the hard work for you.

 

The basics of this is as simple as:

 

string Lang = "de-CH";   // Swiss German

System.Threading.Thread.CurrentThread.CurrentCulture = 

    new System.Globalization.CultureInfo(Lang);

 

From this point forward the current thread will use the various Locale settings provided for dates, numbers separators etc. In WinForms applications you can do this quite nicely by allowing a language selection and setting this selection somewhere at application startup, making sure that any other new threads inherit this value if they generate any UI code to display.

 

You can also do this in Web Applications and it’s almost as trivial. ASP. Net’s Request object has a UserLanguages collection that allows you to read the browser’s currently active language. Ever wonder how Google can tell which language you’re running? When you’re using a German version of IE it will automatically browse to Google.de for example. Well, most modern browsers return a selection of preferred languages which is exactly what the UserLanguages property returns.

 

With this knowledge you can use a fairly generic routine and plug it into your ASP.Net base Page subclass (you are using a Subclass aren’t you???). Start by creating a generic routine in your utility library (I use wwWebUtils for this):

 

public static void SetUserLocale(string CurrencySymbol)

{

      HttpRequest Request = HttpContext.Current.Request;

      if (Request.UserLanguages == null)

            return;

 

      string Lang =  Request.UserLanguages[0];

      if (Lang != null)

      {

            if (Lang.Length < 3)

                  Lang = Lang + "-" + Lang.ToUpper();

            try

            {

                  System.Threading.Thread.CurrentThread.CurrentCulture = 

                                     new System.Globalization.CultureInfo(Lang) ;

                 

                  if (CurrencySymbol != null && CurrencySymbol != "")

                      CurrentThread.CurrentCulture.NumberFormat.CurrencySymbol =

                              CurrencySymbol;

            }

            catch

            {;}

      }

}

 

Notice that I’m using a parameter here to allow overriding the Currency Symbol. In my apps though I’ve found that I often need to adjust the number format but I don’t want to also format the currency symbol because my application needs to still run with currency of US dollars regardless of the locale used. Only if I actually perform translations into other currencies would it be possible to show currency in the locale native format.

 

You can call this method generically from global.asax’s BeginRequest method then with the currency of your choice or null if you indeed want the currency symbol to switch as well:

 

wwWebUtils.SetUserLocale( System.Threading.Thread.CurrentThread.

                        CurrentCulture.NumberFormat.CurrencySymbol );

 

(all on one line)

 

This will take the default currency symbol (ie. $ on my Web Server and associate it with the locale). If somebody from Germany now shows up they’ll see numbers represented in German number format but instead of the Euro sign they’ll still see the US dollar sign.

 

That’s all it takes. Note that if the browser doesn’t provide Locale info – and many older versions don’t – the code continues to run in the default Locale. ASP.Net assigns the default Locale to each request when it starts with the default being the Locale that the Web Server is running under. In my case that would be US English (en-Us).

 

This is a cool feature if you think about it especially if you realize how trivial the implementation for all of this is. However, the full process of localizing an application is full of pitfalls… I’ll have more on this stuff as I move forward.