ASP.NET Change Culture for ONLY Currency not date, etc - asp.net

I have a base class that inherits a page and changes the culture based on a pre-determined value set in the database. I need the culture to change the currency symbol but nothing else. If the value in the db says en-GB I need for it to change all currency values on the page to British pounds, and if it sais en-US show a US Dollar Sign. I need the culture variable to only effect the currency and nothing else, all dates, etc should be in the default culture(en-US)
Any ideas?

Basically you need to use a format provider when formatting your numbers as currency. Have a look at the following example:
public static string CulturedCurrency(decimal number,string culture = "en-US")
{
NumberFormatInfo numberInfo = CultureInfo.CreateSpecificCulture(culture).NumberFormat;
return number.ToString("c",numberInfo);
}
Reference: http://geekswithblogs.net/dtotzke/articles/24573.aspx
If you want to do it inline on databinding have a look at the code here: Format string by CultureInfo

I have found the solution I was looking for. Going through and changing each element of currency to use the specified culture was not something that would be easily done so I started playing with other options and what I have found was that if I used the culture function in my base class I could do the following:
System.Globalization.CultureInfo ci;
if (culture == "")
{
ci = new System.Globalization.CultureInfo("en-US");
}
else
{
ci = new System.Globalization.CultureInfo(culture);
}
System.Threading.Thread.CurrentThread.CurrentCulture = ci;
System.Threading.Thread.CurrentThread.CurrentUICulture = ci;
ci.DateTimeFormat.ShortDatePattern = "MM/dd/yyyy";
ci.DateTimeFormat.LongDatePattern = "dddd, MMMM dd, yyyy";
ci.DateTimeFormat.DateSeparator = "/";
This will set the culture to what I want and then set the date of the culture (no matter what the culture is) to the US Format of the datetime. Thanks for all the help!

Most ToString methods take a format provider; the Culture Info is a format provider. You are going to have to leave the current culture as en-US and manually format the currency values using the ToString() method.
http://msdn.microsoft.com/en-us/library/3ebe5aks.aspx
HTH.

using System.Globalization;
...
value.ToString(CultureInfo.CreateSpecificCulture("en-US"));

A little add on Rob's answer, if you have a localization attribute in your URL, and thus setting the Culture on every request, you might just want to do it like this:
//get language attribute from url. (requires special routing in MVC)
string lang = (string)filterContext.RouteData.Values["lang"] ?? _DefaultLanguage;
switch (lang)
{
case "nl":
lang = "nl-NL";
break;
case "en":
lang = "en-GB";
break;
case "en-US":
lang = "en-US";
break;
default:
lang = _DefaultLanguage;//nl-NL
break;
}
NumberFormatInfo numberInfo = CultureInfo.CreateSpecificCulture("nl-NL").NumberFormat; //always use euros as currency
CultureInfo info = new CultureInfo(lang);
info.NumberFormat = numberInfo;

Related

How do I make sure that a decimal value is passed with a "." separator when I consume an API in asp.net Core?

I made an API that looks like this
[HttpPost]
[Route("/products")]
public async Task<IActionResult> Add([FromBody]ProductDTO productDTO) {
Product newProduct = await _productsService.Add(productDTO);
return Ok(Mapper.Map<ProductDTO>(newProduct));
}
The ProductDTO has a Price property and has a decimal type.
I want to make sure that if a move my application to another server with a different locale, it will still accept a "." as separator. For instance, if I move it to a server that has a locale in Italy, I want to make sure that the separator won't change to ",".
Does setting the culture info in the Startup.Configure solve my problem?
var cultureInfo = new CultureInfo("en-US");
cultureInfo.NumberFormat.CurrencyDecimalSeparator = ".";
CultureInfo.DefaultThreadCurrentCulture = cultureInfo;
CultureInfo.DefaultThreadCurrentUICulture = cultureInfo;
I tried to change the locale of the computer that I'm currently using for development, and it works. But I want to know if someone had problems when he/she deployed the application to another server.

ASP.NET MVC5 stores date in wrong format

last days I have a quite hard time to convince MVC5 project to work with dates as I would like to. After intensive googling I've tried numerous attepmts to make it work properly, but without success.
Here is the problem:
I need to display and edit dates on my webpage in format dd.MM.yyyy (i.e. 15.07.2015). For editing I also need to use jquery ui datepicker. The thing here is that I've been able to successfully set that datepicker to display date in requested format, also the jquery validation is now correctly validating the date in given format. So as for UI so far so good. The problem appeared in moment, when I clicked submit button - there was an error message like:
The value '15.07.2015' is not valid for Start Date.
After brief investigation I've found that when the date is passed to server it has switched format - instead of dd.MM.yyyy the date is treated like MM.dd.yyyy. In other words the error pops up only when the day part of date is higher than 12.
Here are some highlights from my code:
In my model for date I have this:
[Required]
[Display(Name = "Start Date")]
[DataType(DataType.Date)]
[UIHint("Date")]
[DisplayFormat(DataFormatString = "{0:dd.MM.yyyy}", ApplyFormatInEditMode = true)]
public DateTime DateStarts;
Which I believe is everything I need to do to make that date display in specified format and also force users to fill the textbox with date in right format.
As given in [UIHint("Date")], I have my own template for rendering textbox for editing date. The implementation of that template is following:
#model Nullable<DateTime>
#{
DateTime dt = DateTime.Now;
if (Model != null)
{
dt = (System.DateTime)Model;
}
#Html.TextBox("", dt.ToString("dd.MM.yyyy"), new { #class = "form-control datecontrol", type = "text", data_val_date = "Field must have format dd.MM.yyyy" })
<i class="fa fa-calendar form-control-feedback lowerzindex"></i>
}
The jquery datepicker has following implementation:
$('.datecontrol').datepicker({
onClose: function () { $(this).valid(); },
minDate: "-1M",
dateFormat: "dd.mm.yy",
});
So even the datepicker knows how the format should look like.
The last component is the validation by jquery.validation:
$.validator.addMethod(
'date',
function (value, element, params) {
if (this.optional(element)) {
return true;
};
var result = false;
try {
$.datepicker.parseDate('dd.mm.yy', value);
result = true;
} catch (err) {
result = false;
}
return result;
},
''
);
I know that the date is passed to server in some culture neutral format, but I thought that when I decorated code on numerous places with the requested format, this will ensure that the conversion into that culture neutral format will be done right. Or am I missing something else ?
Thanks
Your problem lies in the fact that you have not set proper Culture for your application. Your request end-up executing under culture that has month-day-year order (probably under en-US) causing you a problem.
The easiest solution is to set set the culture that actually has day-month-year order and . as date separator in your web.config, for example:
<configuration>
<system.web>
<globalization uiCulture="de-DE" culture="de-DE" />
...
https://msdn.microsoft.com/en-us/library/bz9tc508%28v=vs.140%29.aspx
The MVC uses current culture when parsing and binding posted data to your models/parameters.
It is advised to use same date separator across entire scope - html, client, javascript, server culture, ...

Convert DateTime with a specified language

I am coding a MVC 5 internet application and am wanting to convert a DateTime to be displayed as a LocalTime where I have the language. This is for an Azure website.
Here is my code:
DateTime dateTimeUtcNow = DateTime.UtcNow;
DateTime convertedDate = DateTime.SpecifyKind(dateTimeUtcNow, DateTimeKind.Utc);
DateTime dateTimeLocalTime = convertedDate.ToLocalTime();
return dateTimeLocalTime.ToString(new CultureInfo("en-NZ"));
The output from the above code is the exact same output as if I return the DateTime in UTC with no language culture specified.
How can I convert a DateTime in UTC for a local time where I have the culture language?
Thanks in advance.
You can use the second argument to the toString function and use any language/culture you need...
You can use the "d" format instead of ToShortDateString according to MSDN...
So basically something like this to return as NewZ ealand English:
CultureInfo enAU = new CultureInfo("en-NZ");
dt.ToString("d", enAU);
you could modify your method to include the language and culture as a parameter
public static string ConvertDateTimeToDate(string dateTimeString, String langCulture) {
CultureInfo culture = new CultureInfo(langCulture);
DateTime dt = DateTime.MinValue;
if (DateTime.TryParse(dateTimeString, out dt))
{
return dt.ToString("d",culture);
}
return dateTimeString;
}
You may also want to look at the overloaded tryParse method if you need to parse the string against a particular language/culture...

ASP.NET AJAX is not rendering a __cultureInfo JS object for en-US locales

I'm using the ASP.NET AJAX control on my site and have enabled the following settings on the ScriptManager:
scriptManager.EnableScriptGlobalization = true;
scriptManager.EnableScriptLocalization = true;
When I switch the browser language to, say, French, I get a rich JavaScript object rendered on the page called __cultureInfo that contains all the good stuff I need to initialize date pickers and to properly format date strings.
However, when the locale is US English, the __cultureInfo object isn't rendered.
Is there a way to force ASP.NET AJAX to render this JavaScript variable / object for all locales? I want to initialize all of my locale-aware controls without having to special-case US English.
Microsoft clones the Invarient culture to en-US so even though __cultureInfo is not loaded you should have everything you need in Sys.CultureInfo.CurrentCulture
switch(typeof(cultureInfo)) {
case "string":
// this is true when the server is 3.5
cultureInfo = window.eval("(" + cultureInfo + ")");
// allow fallthrough to object
case "object":
this.CurrentCulture = this._parse(cultureInfo);
delete __cultureInfo;
break;
default:
cultureInfo = clone(invariant);
// fix up the differences
cultureInfo.name = "en-US";
cultureInfo.numberFormat.CurrencySymbol = "$";
var dtf = cultureInfo.dateTimeFormat;
dtf.FullDatePattern = "dddd, MMMM dd, yyyy h:mm:ss tt";
dtf.LongDatePattern = "dddd, MMMM dd, yyyy";
dtf.LongTimePattern = "h:mm:ss tt";
dtf.ShortDatePattern = "M/d/yyyy";
dtf.ShortTimePattern = "h:mm tt";
dtf.YearMonthPattern = "MMMM, yyyy";
this.CurrentCulture = this._parse(cultureInfo);
break;
}

What is the recommend way to create a custom culture and associated resource files for a specific Client?

I have client that wants to specifiy their own version of localized content for a subset of my string resources.
For simplicity here is basic example:
Lets say I have 2 localized strings (showing english content)
PageTitle="Hello World"
PageDescription="This is a more wordy version of Hello World!"
I wish to localize these so I have resource files.
Strings.resx (contains my English
string)
Strings.fr-ca.resx
(contains my French-Canadian strings)
Strings.fr-ca-clientX.resx (contains
my strings for a Client whom is
French-Canadian and therfore very
picky;) - just joking)
Ideally "Strings.fr-ca-clientX" can specify only the strings they want to "override". In other words they may just wish to change the PageTitle and continue using the PageDescription from the "fr-ca" resource file.
So how do I go about this in .NET? Ideally I would just create the resx file and specify the culture in my "Web.config" and it should work...
<globalization uiCulture="fr-ca-clientX" culture="fr-ca-clientX" />
However, this does not work. "The tag contains an invalid value for the 'culture' attribute" is my first obsticle.
Thanks,
Justin
public void AddCustomCulture(string cultureName, string baseCulture)
{
var cultureBuilder = new CultureAndRegionInfoBuilder(cultureName, CultureAndRegionModifiers.None);
cultureBuilder.LoadDataFromCultureInfo(new CultureInfo(baseCulture));
var region = baseCulture.Substring(3, 2);
cultureBuilder.LoadDataFromRegionInfo(new RegionInfo(region));
cultureBuilder.Register();
}
You can create a new culture with the following code:
//Get culture info based on Great Britain
CultureInfo cultureInfo = new CultureInfo( "en-GB" );
RegionInfo regionInfo = new RegionInfo( cultureInfo.Name );
CultureAndRegionInfoBuilder cultureAndRegionInfoBuilder = new CultureAndRegionInfoBuilder( txtCultureName.Text, CultureAndRegionModifiers.None );
cultureAndRegionInfoBuilder.LoadDataFromCultureInfo( cultureInfo );
cultureAndRegionInfoBuilder.LoadDataFromRegionInfo( regionInfo );
// Custom Changes
cultureAndRegionInfoBuilder.CultureEnglishName = txtCultureName.Text;
cultureAndRegionInfoBuilder.CultureNativeName = txtNativeName.Text;
cultureAndRegionInfoBuilder.Register();
I have written a post on creating an app to do just that..
http://wraithnath.blogspot.com/search/label/Globalization
You probably need to create your own culture and register it. You'll find MSDN article on that topic here.
You don't need to alter culture attribute, it should stay at "fr-CA", as uiCulture attribute is responsible for loading strings from resources.

Resources