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 .
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
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
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
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
# re: Detecting and setting the Locale on the Current ASP.Net Web Request
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
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
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
Thanks for the post... it was exactly what i needed.
# re: Detecting and setting the Locale on the Current ASP.Net Web Request
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
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
# get client regional setting date format
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
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!
# re: Detecting and setting the Locale on the Current ASP.Net Web Request
# re: Detecting and setting the Locale on the Current ASP.Net Web Request
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
# Getting ISO 3166-1 numeric From Culture or Region Info
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?
# re: Detecting and setting the Locale on the Current ASP.Net Web Request
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
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
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
# re: Detecting and setting the Locale on the Current ASP.Net Web Request
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
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...