Rick Strahl's Weblog  

Wind, waves, code and everything in between...
.NET • C# • Markdown • WPF • All Things Web
Contact   •   Articles   •   Products   •   Support   •   Advertise
Sponsored by:
Markdown Monster - The Markdown Editor for Windows

Detecting and setting the Locale on the Current ASP.Net Web Request


:P
On this page:

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.


The Voices of Reason


 

# RE: Detecting and setting the Locale on the Current ASP.Net Web Request

For ASP.NET, if you do not have a subclassed page class (even if you do), it is probably a good idea to set the thread locale from Global.asax in the BeginRequest() method.

Also, we've found that not all locales from the browser exist in the framework, so we had to write code to try the first one in the list, then try it without the locale (es-US should be U.S. Spanish, but the framework only knows about Spanish), then, if we still can't get a "hit", we continue through the other languages they have listed. If we can't find anything, we default to the locale of the server (en-US in our case).

Rick Strahl
March 30, 2004

# re: Detecting and setting the Locale on the Current ASP.Net Web Request

Michael, good points especially about BeginRequest. Duh! I noticed about the Locale strings not always being available too. The code actually needs an exception block to check for failures as well. The code I have does check for the language only case which the browser seems to use for things like de-DE (high German) for example. If I get two characters only I dupe the string out to the 5 char version.
Very useful stuff all of this - great mileage for very little effort!

Michael Falconer
July 24, 2004

# re: Detecting and setting the Locale on the Current ASP.Net Web Request

I'm currently looking at implementing code like the above, but have one question; if the user has a number of languages set up in their browser, why limit the code to trying only the first language?

For example, if the users first language is Arabic, and you have no Arabic resources, then they will see the default locale (possibly English). But if their second language is Spanish, and you do offer Spanish resources, it would be better to use those.

My only difficulty so far has been in trying to discover which resources are being used for each locale. It looks like you've got to use the ResourceManager, but none of the code I've tried is successful.

Any ideas on how to discover this?

Rick Strahl
July 24, 2004

# re: Detecting and setting the Locale on the Current ASP.Net Web Request

Michael, The browser actually will return the user's language preferences IF he has more than one configured. If you parse through UserLanguages() you can get the list of languages from there.

Rick Strahl's WebLog
August 13, 2004

# Switching CurrentCulture in ASP.NET Pages Gotchas

Switching the CurrentCulture in ASP.NET is almost trivial to do, but beware of some of the side effects it might have on your applications.

Scott McMaster
February 14, 2005

# re: Detecting and setting the Locale on the Current ASP.Net Web Request

Thanks Rick. This whole area seems to be fraught with pitfalls. I recently ran into trouble handling the neutral cultures. I discovered that, rather than shooting for a specific culture by appending an upper-cased version of the neutral letters and doing "new CultureInfo()", you can be "right" more of the time by using "CultureInfo.CreateSpecificCulture()", passing in the neutral (two-letter) culture code as follows:

Thread.CurrentThread.CurrentUICulture = CultureInfo.CreateSpecificCulture( lang );

Look at the example output in the CreateSpecificCulture help topic to see what I mean.

Even then, though, it looks like you have to add exception-handling code for at least CHS and CHT, and somehow do a different "right" thing in that case...

Rick Strahl's WebLog
January 10, 2006

# Hungarian Characters and DataRow String Field indexes

One more time I've run into an issue where I'm reading a field from a DataRow only to find that the current Locale I'm running in doesn't like the field name and fails to retrieve the field. This time it's Hungarian which seems to have some odd combinations that do and don't work.

Af
April 27, 2006

# re: Detecting and setting the Locale on the Current ASP.Net Web Request

I am a newbie to ASP.Net.
Can someone let me know how similar the locale in .Net is to Java's Locale implementation?

Many thanks

Jean Renier
June 13, 2006

# re: Detecting and setting the Locale on the Current ASP.Net Web Request

In my opininion the right place to put this code is in de method InitializeCulture which you have to override in a page base class.

protected virtual void InitializeCulture()
{
wwWebUtils.SetUserLocale( System.Threading.Thread.CurrentThread. CurrentCulture.NumberFormat.CurrencySymbol );
base.InitializeCulture();
}


Rick Strahl
June 13, 2006

# re: Detecting and setting the Locale on the Current ASP.Net Web Request

Jean - the problem is that it's part of the Page class so you have to have a custom page sub class to make this happen. This is reasonable, but sometimes you just don't have this available, nor do you in other cases want to do this translation and doing it higher up in the ASP.NET gives you better application level control.

Robert
September 04, 2006

# Getting ISO 3166-1 numeric From Culture or Region Info

Hi

How can i get the ISO 3166-1 numeric country code using .Net from either the culture or Region Info classes or some other class?

Rick Strahl's WebLog
September 09, 2006

# Auto Culture Mapping in ASP.NET 2.0 and Caching in ASP.NET 2.0 Pages

I ran into some issues today dealing with caching in a localized page. Apparently caching - even with VaryByParm based on the culture - doesn't quite work correctly to get caching to work correctly with culture specific mapping.

Rick Strahl's Web Log
September 28, 2006

# DataRows, String Indexes and case sensitivity with Turkish Locale - Rick Strahl's Web Log


Web Forms
November 02, 2006

# ASP.NET Forums - Is it possible to get the remoute client OS version ?


Floyd
November 23, 2006

# re: Detecting and setting the Locale on the Current ASP.Net Web Request

Hi,
I've tried the aproach mentioned in the article and it works fine, except that when i try to export the data to excel, i get numbers that have the decimal seperator of the locale setting but not the thousands separator(i am using the locale setting as german).for eg, i am able to view a report with data 18.600,23 but when i expot to excel i get 18600,23.
What could be the problem.
Thanks,
Floyd

Visual Studio 2005
December 14, 2006

# ASP.NET Forums - Messagebox Button? in .net 2005


Localization
February 07, 2007

# ASP.NET Forums - Render Existing site in multiple languages


ASP.NET Forums
May 18, 2007

# Is it possible to get the remoute client OS version ? - ASP.NET Forums


ASP.NET Forums
May 25, 2007

# Messagebox Button? in .net 2005 - ASP.NET Forums


ASP.NET Forums
June 05, 2007

# Render Existing site in multiple languages - ASP.NET Forums


Doru
June 13, 2007

# re: Detecting and setting the Locale on the Current ASP.Net Web Request

Hi,

Is it possible to read the client regional settings using an asp.net page?
One of the users have a modified setting in the Regional Options, he's using English(US), but Digit Grouping Symbol is not ",", he has changed to " ". I need to get this value from the client and to set the numeric format on the screen.

Thanks,

Doru

mswin
October 30, 2007

# re: Detecting and setting the Locale on the Current ASP.Net Web Request

Hi,
How to get the user language setting from web service.
If the web service is invoked directly from the webservice, I am able to get the Request headers of the request object.
But if the same web service is invoked from aspx page using javascript, the request headers are null.

Regards

Olavo Alexandrino
January 24, 2008

# re: Detecting and setting the Locale on the Current ASP.Net Web Request

Hello!

First congrats for the article.

So, I could implement successfully the localization and internalization for my personal web site.

I used the following way to do it.

By the first time, if there is no default locale I set "pt-BR" as default automatically.

If somebody who's accessing the site want, he/she can change to us-US.

The point is that by setting the locale up automatically, it's avoiding the site to be indexed by google search, for instance.

What would be the first point (o better) on the ASP.NET page's cycle life that I can use "HttpContext.Current.Request" and set the locale up according to user's browser?

thanks!

Rick Strahl
January 24, 2008

# re: Detecting and setting the Locale on the Current ASP.Net Web Request

HttpApplication.BeginRequest is the first point of entry and you can set the locale there.

ram
January 30, 2009

# get client regional setting date format

hi,

how to get client system regional setting date format instead of browser date format. Any idea about that?

Thanks in advance.

Rick Strahl
March 18, 2009

# re: Detecting and setting the Locale on the Current ASP.Net Web Request

@Ram - you can't get the regional setting of the client system unless you ask for it. However, why would you need that? If the browser is running in a specific language, wouldn't you want to respect that?

Raghavendra
May 04, 2009

# re: Detecting and setting the Locale on the Current ASP.Net Web Request

Hi,

I am using Sharepoint 2007 with C# and javascript for clientside validation. I want to know on the client side what is the Date format in the regional settings for the current page.

Ex : If it is Hindi in the regional settings for the page in current site , then i want the information to be fetched in javascript as "dd-mm-yyyy" , if it is en-UK then "mm/dd/yyyy" and so on.

Please let me know how i can get this information in the javascript file that i use for validation

Rick Strahl
May 05, 2009

# re: Detecting and setting the Locale on the Current ASP.Net Web Request

@Raghavendra - the client side has no direct API for formatting dates so anything you do will either require code or some library. I think the closest thing you're likely to find is datejs: http://www.datejs.com/2007/11/27/getting-started-with-datejs/, but even it requires that you load a script library for a specific locale when the page loads.

Another way that you can do this if you are dealing with isolated dates is: Render the dates on the server and embed them into the page as strings (<%= %> tags or embedded JavaScript), or use an AJAX callback to format the dates dynamically as needed. This is fine as long as you don't have tons of dates (like in a list/grid type display).

Daniel
October 08, 2009

# re: Detecting and setting the Locale on the Current ASP.Net Web Request

It is possible in a web application, detect the user's regional settings?

I think it's possible detect the regional settings of the server host, but, i need detect the user's, to format an csv file.

Thank you

Daniel

Tim
April 01, 2010

# re: Detecting and setting the Locale on the Current ASP.Net Web Request

Still very useful six years later.

Thanks for the post... it was exactly what i needed.

Ron
June 24, 2010

# re: Detecting and setting the Locale on the Current ASP.Net Web Request

A very helpful article.. thanks!
I have a website where I need to check the user's browser setting and redirect them to a different URL.

I tried doing this in global.asax Session_Start method, but having problems with google's indexing.

When I try with Application_BeginRequest, every resource request(images, css, etc) goes through this method and seems to affect the css. Whats the best way to acheive this?

Any solutions? Thanks again!

West Wind  © Rick Strahl, West Wind Technologies, 2005 - 2024