ASP.NET Globalization -- Displaying dates - c#

Good morning,
Apologies for the newbie question. I'm just getting started with ASP.NET internationalization settings.
Background info:
I have a website which displays a <table> HTML object. In that <table> HTML object, I have a column which displays dates. My server being in the US, those dates show up as MM/DD/YYYY. Many of my users plug into this webpage through Excel, via the Data --> Import External Data --> Import Web Query interface. My users, for the most part, are in the US, so those dates show up correctly in their Excel screens.
Now I need to make the webpage work for UK users. As is, they are downloading the dates as MM/DD/YYYY, which makes their spreadsheets unusable since their regional settings are set to DD/MM/YYYY.
My question is:
How do I make it so the web server realizes that the incoming request has a en-GB culture setting? I could engineer my own little custom workaround, but I'm sure I'm not the first programmer to come across this. How do the pro's handle this? I'm looking for a solution that would be relatively simple and quick to put up, but I don't want to just put some crappy buggy piece of my own logic togethe that I'm going to dread 6 months from now.
Thanks a lot in advance,
-Alan.

A couple of points:
The <globalization> element also needs the attribute culture="auto". The uiCulture attribute affects the language used to retrieve resources. The culture attribute affects the culture used for formatting numbers an dates.
As noted in this MSDN article, it is not a best practice to rely exclusively on browser settings to determine the UI culture for a page. Users frequently use browsers that are not set to their preferences (for example, in an Internet cafe). You should provide a method for users to explicitly choose a language or language and culture (CultureInfo name) for the page.

You can allow the browser to set your UI culture automatically if you wish, by opening up the web.config, like this:
<configuration>
<system.web>
<globalization uiCulture="auto" />
...
And then the culture set by the browser will be automatically set in your app. This means that when you have the framework display date/time values, they will be formatted according to the current thread's UI Culture.
This will also help if you are using currency and/or localized text (however you have to provide the localized resources for each culture you support).

You could also accept a query string parameter for overriding the culture settings.
Culture initialization should go in the Page.InitializeCulture method.
protected override void InitializeCulture ( )
{
Thread.CurrentThread.CurrentCulture
= Thread.CurrentThread.CurrentUICulture
= Request.QueryString [ "culture" ] != null ? new CultureInfo ( Request.QueryString [ "culture" ] ) : CultureInfo.InvariantCulture;
//base.InitializeCulture ( );
}
Usage: http://tempuri.org/page.aspx?culture=en-GB

Related

Asp.net core Localization in Razor Pages

How do I change the position of a string or html snippet to suit the language when displaying an html snippet or script in another language in razor
for example:
"Flights to Antalya for a price starting from €39.99"
would be change to
"€39,99’dan başlayan fiyatlarla Antalya uçuşları"
translating from turkish to english : their position will change
just use formatted string in the related resource file:
resources.en.resx:
"Flights to Antalya for a price starting from {0}"
or resources.tr.resx:
"{0}’dan başlayan fiyatlarla Antalya uçuşları"
Then you can use the default IStringLocalizer as below:
_localizer["{0}’dan başlayan fiyatlarla Antalya uçuşları", price]
I find from somewhere
ClientResources.en.resx
After you can take instance from the reference on the page
R = Settings.Resources !== undefined ? Settings.Resources : {},
you can use when needed
if (totalPassengerCount > maximumPassengerCount) {
alert(R.MaximumPassengerCount);
I think, you can use Culture and UICulture. Every request set the language in layout.
Exp;
#{
Layout = "~/_Layout.cshtml";
if(!Request["lang"].IsEmpty()){
Culture = UICulture = Request["lang"];
}
}
Language dependent define for use ToString(iformatter).
Exp;
Currency: #(10000.ToString("c")
FR For: £
EN For: €
You mainly need 2 things:
A automated way to set the user's current culture in an http requestso that CultureInfo.CurrentCulture contains the desired language + region (a.k.a culture)
A way to read translated text from a resource file (resx) according to the specified culture
Things like Dates, for example, are automatically formatted according to the current culture.
[This is an article about localization with AspNet Core Razor Pages and/or MVC]to understand the process (https://sunnyatticsoftware.com/blog/webs-multilingue-localizacion-mvc-razor-pages) it is in Spanish (hopefully you can have the browser translate it in a good enough way), but at the end it shows how to achieve this with Razor Pages in C#.

User!Language vs CurrentThread

For formatting our Dates in the RDL-Files, we use the following format:
=First(FormatDateTime(Fields!SomeDate.Value, 2))
According to this Page, it should take the Computer's Regional Settings.
The problem is: If I call the Reporting-Service via another Service and try to set the Language:
rs.SetExecutionParameters(MapParameters(Report.Parameters).ToArray(), "de-CH");
This gets ignored. I tried to override the Thread-Cultures via
System.Threading.Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo("de-CH");
System.Threading.Thread.CurrentThread.CurrentCulture = new System.Globalization.CultureInfo("de-CH");
Which gets ignored as well.
Whats really string: The Reporting-Server itself has de-CH as culture as well, but it keeps using the english date-format.
Can someone tells me what's meant with "Computer's Regional Settings" and why the Reporting-Service refuses to take the passed Culture?
Edit: The language in the Report is
=User!Language
Generally said I'd like to pass the Report-Language from outside, be it via CurrentThread or via Parameter. But both get ignored.
Short Answer
Instead of FormatDateTime, you could use Format and specify your expected output format:
=First(Format(Fields!SomeDate.Value, "dd.MM.yyyy"))
Or another alternative to have the culture in a parameter, but in this case you will have to read the long answer.
Long answer
Your first attempt with the SetExecutionParameters was to set the culture of the parameters, which does not affect the report itself (only the parameters you pass to it).
Your second attempt was to change the culture of the client application, which also does not affect the report (only the client application culture).
The FormatDateTime function usually uses the computer regional settings, but not in Reporting Services. It will take the report culture, which in your case is User!Language.
User!Language returns the language configured in the client web browser when browsing to the report server.
I'm not sure what the behavior is when calling from web services (a specific setting taken or default to en-US).
The Report Language property can be an expression, so nothing stops you from adding another text parameter to the report, say, ReportCulture, and use this in Properties => Language:
=Parameters!ReportCulture.Value
You would have to keep using your expression for the dates:
=First(FormatDateTime(Fields!SomeDate.Value, 2))
You can configure a default value (de-CH in your case), so that this setting will only be specified if you want to override it.

Use of CultureInfo.InvariantCulture

I'm working on a project that uses decimals in a textbox. I'm currently developing in a machine that has decimal separators set to "," instead of "." so I had to use this sentence when parsing text string into decimal:
decimal number = Decimal.Parse(number.Text, CultureInfo.InvariantCulture);
Now... Is CultureInfo.InvariantCulture the right thing to do or should I use CurrentCulture instead?
Thank you,
Matias.
For user input, you usually want CultureInfo.CurrentCulture. The fact that you're using a locale that's not natural to you is not the usual user case - if the user has , as the decimal point in their whole system, they're probably used to using that, instead of your preferred .. In other words, while you're testing on a system with locale like that, learn to use , instead of . - it's part of what makes locale testing useful :)
On the other hand, if you're e.g. storing the values in a configuration file or something like that, you really want to use CultureInfo.InvariantCulture.
The thinking is rather simple - is it the user's data (=> CurrentCulture), or is it supposed to be global (=> InvariantCulture)?
If you do a correctly internationalized program...
A) If you are using Winforms or WPF or in general the user will "work" on the machine of the program, then input parsing should be done with the CurrentCulture
B) If you are web-programming, then the user should be able to select its culture, and CurrentCulture (the culture of the web-server) should be only used as a default
And then,
A) data you save "internally" (so to be written and then read by your program) should use InvariantCulture,
B) data you interchange with other apps would be better to be written with InvariantCulture (unless the other app is badly written and requires a specific format),
C) files you export to the user should follow the previous rules (the ones about user interface), unless you are using a "standard-defined format" like XML (then use Xml formatters)

How use a specific CultureInfo in Asp.net Web API

I've recently added WEB API to an existing VS desktop application and everything worked fine, until yesterday when I had to add a GET method that took three parameters, one of them a Date.
Well, at first I thought that that was going to be a piece of cake, but much to my surprise I noticed that when I sent 2014/07/09 (9th July) on the server where the application was installed it was treated like 2014/09/07 (7th September) and for that reason all my comparisons never worked.
I have tried things like changing from a GET method to a POST method, changing my Regional and Language Options settings to the same on the server, passing the date as a String a created a Datetime object on the server using the parts of the string. Unfortunately none of them worked.
Then I remember that this desktop application have some methods on its WCF project (which I'm passing now to web API) that passed dates with no problem at all. Looking in the code for a while I found that they used something like this on every class of they WCF project that uses dates:
Imports System.Globalization
Imports System.Security.Permissions
Imports System.Threading
Public Class ServicioRemotoVentas
Implements IServicioRemotoVentas
Public Sub New()
MyBase.New()
Thread.CurrentThread.CurrentCulture = New CultureInfo("es-PE", False)
End Sub
Surely this Thread.CurrentThread.CurrentCulture = New CultureInfo("es-PE", False), must be there for something.
Now I would like to know if you have used something like that in Web API before? if so how and where did you put such a configuration.
These are the settings on my pc :
And these are the server settings:
I almost forgot to mention that I pass all the dates using this format yyyy/M/d with all the other parameters using json.
Is it perhaps that when the string is deserialized in the Web API this is done using the system date format because I haven't specify the culture info to use?? or maybe it is a Json error when trying serialize/deserialize the dates??
As always, any advice or resources you could provide would be greatly appreciated.
As discussed in the comments, the ASP.NET runtime does have a solution for these scenarios: it is the web.cofig element <globalization> - (see MSDN <globalization> Element)
It's structure is defined as:
<configuration>
<system.web>
<globalization
enableClientBasedCulture="true|false"
requestEncoding="any valid encoding string"
responseEncoding="any valid encoding string"
fileEncoding="any valid encoding string"
responseHeaderEncoding = "any valid encoding string"
resourceProviderFactoryType = string
enableBestFitResponseEncoding = "true|false"
culture="any valid culture string"
uiCulture="any valid culture string"/>
So, in case, that we want to force server/dev workstation to act in en-US culture we should use these explicit settings:
<globalization
enableClientBasedCulture="false"
uiCulture="en-US"
culture="en-US" />
This will use the proper (desired and set) culture for any http request.
Also interesting could be the default setting overview:
<globalization
requestEncoding="utf-8"
responseEncoding="utf-8"
fileEncoding=""
culture=""
uiCulture=""
enableClientBasedCulture="false"
responseHeaderEncoding="utf-8"
resourceProviderFactoryType=""
enableBestFitResponseEncoding="false" />
See also similar here:
Set uiCulture automatically based on browser accept language
How to change my computer's cultureInfo
and the globalization Element itself
It is mentioned in your question that the input is a string not a datetime object ("I almost forgot to mention that I pass all the dates using this format yyyy/M/d").
Your service interface isn't posted but I guess that the parameter type is DateTime and this is why the deserialization is incorrect.
Although the setting posted by Radim works it's not a fix but a hack/workaround.
There are two recommended ways to implement this:
Use strings at both ends, i.e. the API parameter should also be string and the API specification should state what date format to use. Use DateTime.Parse(String, IFormatProvider) and specify the culture in contract (i.e. new CultureInfo("es-PE")) when the input string is converted to DateTime.
https://msdn.microsoft.com/en-gb/kc8s65zs
Use date objects at both ends. In this case the serializer will serialize the date object to a well known, culture independent format and the desrializer will deserialize the string to correct DateTime object.
public void GetOrders(DatetTime fromDate)
I'd go with #2 because is generic and doesn't force the client to use a specific culture.
See also:
The "right" JSON date format

Detect User's Country in .CS File

I have an application that needs to detect the user's country so I can adjust dates to that expectation for that country. I do have JS that is working already in detecting the locale. Now, I understand that JS is browser side and my CS file is server side. Is there a way to either:
1) Link that JS's answer up to my CS
or
2) Detect the locale within the CS file?
Thank you for your time
Kevin
Well, detecting the user's country isn't really the issue. If you need to format dates, you need to use something like this to detect the current culture rather than the country:
CultureInfo currentCulture = Thread.CurrentThread.CurrentCulture;
You wouldn't want to detect the country as there's plenty of users in a given country that don't use the program in that country's culture. For example, say someone has their system set to Spanish, but they live in the USA. You'd force them to use English, but using this method, you can take it directly from the system setting instead. Being dynamic is good!
That way, when you output a date, you can do something like this:
// Displays dt, formatted using the ShortDatePattern
// and the CurrentThread.CurrentCulture.
Console.WriteLine(dt.ToString("d"));
Reference: http://msdn.microsoft.com/en-us/library/5hh873ya(v=vs.90).aspx
See also: http://msdn.microsoft.com/en-us/library/system.globalization.cultureinfo.currentculture.aspx

Categories