Contact   •   Products   •   Search

Rick Strahl's Web Log

Wind, waves, code and everything in between...
ASP.NET • C# • HTML5 • JavaScript • AngularJs

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


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.

Make Donation


Feedback for this Post

 
# RE: Detecting and setting the Locale on the Current ASP.Net Web Request
by mearls@hotmail.com (Michael Earls) March 29, 2004 @ 2:15am
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).
# re: Detecting and setting the Locale on the Current ASP.Net Web Request
by Rick Strahl March 30, 2004 @ 6:11am
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!
# re: Detecting and setting the Locale on the Current ASP.Net Web Request
by Michael Falconer July 24, 2004 @ 7:48am
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?
# re: Detecting and setting the Locale on the Current ASP.Net Web Request
by Rick Strahl July 24, 2004 @ 2:43pm
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.
# Switching CurrentCulture in ASP.NET Pages Gotchas
by Rick Strahl's WebLog August 13, 2004 @ 8:07am
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.
# re: Detecting and setting the Locale on the Current ASP.Net Web Request
by Scott McMaster February 14, 2005 @ 5:47am
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...
# Hungarian Characters and DataRow String Field indexes
by Rick Strahl's WebLog January 10, 2006 @ 11:45pm
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.
# re: Detecting and setting the Locale on the Current ASP.Net Web Request
by Af April 27, 2006 @ 9:59am
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
# re: Detecting and setting the Locale on the Current ASP.Net Web Request
by Jean Renier June 13, 2006 @ 8:51am
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();
}

# re: Detecting and setting the Locale on the Current ASP.Net Web Request
by Rick Strahl June 13, 2006 @ 1:10pm
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.
# Getting ISO 3166-1 numeric From Culture or Region Info
by Robert September 04, 2006 @ 10:45am
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?
# Auto Culture Mapping in ASP.NET 2.0 and Caching in ASP.NET 2.0 Pages
by Rick Strahl's WebLog September 09, 2006 @ 6:32pm
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.
# DataRows, String Indexes and case sensitivity with Turkish Locale - Rick Strahl's Web Log
by Rick Strahl's Web Log September 28, 2006 @ 7:13pm
# ASP.NET Forums - Is it possible to get the remoute client OS version ?
by Web Forms November 02, 2006 @ 6:34am
# re: Detecting and setting the Locale on the Current ASP.Net Web Request
by Floyd November 23, 2006 @ 10:58pm
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
# ASP.NET Forums - Messagebox Button? in .net 2005
by Visual Studio 2005 December 14, 2006 @ 4:47pm
# ASP.NET Forums - Render Existing site in multiple languages
by Localization February 07, 2007 @ 11:41am
# Is it possible to get the remoute client OS version ? - ASP.NET Forums
by ASP.NET Forums May 18, 2007 @ 6:20am
# Messagebox Button? in .net 2005 - ASP.NET Forums
by ASP.NET Forums May 25, 2007 @ 3:21am
# Render Existing site in multiple languages - ASP.NET Forums
by ASP.NET Forums June 05, 2007 @ 4:23pm
# re: Detecting and setting the Locale on the Current ASP.Net Web Request
by Doru June 13, 2007 @ 6:53am
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
# re: Detecting and setting the Locale on the Current ASP.Net Web Request
by mswin October 30, 2007 @ 1:39am
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
# re: Detecting and setting the Locale on the Current ASP.Net Web Request
by Olavo Alexandrino January 24, 2008 @ 12:21pm
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!
# re: Detecting and setting the Locale on the Current ASP.Net Web Request
by Rick Strahl January 24, 2008 @ 12:25pm
HttpApplication.BeginRequest is the first point of entry and you can set the locale there.
# get client regional setting date format
by ram January 30, 2009 @ 2:37am
hi,

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

Thanks in advance.
# re: Detecting and setting the Locale on the Current ASP.Net Web Request
by Rick Strahl March 18, 2009 @ 2:53am
@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?
# re: Detecting and setting the Locale on the Current ASP.Net Web Request
by Raghavendra May 04, 2009 @ 11:24pm
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
# re: Detecting and setting the Locale on the Current ASP.Net Web Request
by Rick Strahl May 05, 2009 @ 3:13am
@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).
# re: Detecting and setting the Locale on the Current ASP.Net Web Request
by Daniel October 08, 2009 @ 11:10am
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
# re: Detecting and setting the Locale on the Current ASP.Net Web Request
by Tim April 01, 2010 @ 8:12am
Still very useful six years later.

Thanks for the post... it was exactly what i needed.
# re: Detecting and setting the Locale on the Current ASP.Net Web Request
by Ron June 24, 2010 @ 11:59am
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 - 2014