I’m having a bit of a curious problem with .NET and working with the decimal type. My web application uses the following globalization settings:
<globalization culture="auto" enableClientBasedCulture="true"/>
With that in mind, consider the following: the decimal value 123.00 becomes £123.00 in GBP, and EUR 123,00 (note the comma). The problem I’m having appears when I want to go from a decimal value of 123,00 (EUR) back to GBP again, as it becomes 123,000 – which is a huge problem.
In this scenario, my application has consults a look up table based on the detected culture and shows prices in that currency. The problem only arises when the user has made a selection and the data is prepared for sending to our payment gateway, which convers the EUR 123,00 to 123,000.
Any ideas how I can overcome this?
Thanks to everyone who offered their experience and suggestions.
Implementing a custom-type/structure for holding my own Decimal values wasn’t really what I was after, and wouldn’t really give me the functionality I needed (I can already display decimal values in the appropriate local currency/format, I just couldn’t convert them back into UK format when required).
The problem was this line in the web config:
Setting culture = “auto” was allowing .NET to set the locale according to the values provided by the browser (incidentally, by the way, ‘enableClientBasedCulture’ is not implemented, according to MSDN – so you can omit it). Hence, if a visitor from France (with language ‘fr-FR’ configured in their browser) visited our site, all the number formatting would work perfectly (correct decimal separator and currency symbol) but I’d have a problem later when trying to conver that number from it’s European format to the UK/US format I required.
It’s odd, but converting “123.00” to the ‘fr-FR’ locale produces a FormatException because “123.00” is not valid in the French locale (it expects “123,00”). But, converting “123,00” (fr-FR) to the UK/US ‘en-GB’ or ‘en-US’ format does NOT produce an error, but instead the value becomes “123,000”. I believe this should throw a FormatException because it is not acceptable to add another zero.
The solution I implemented was as follows:
Since my existing code connects to our data source to retrieve the correct decimal values dependant on country, all I had now was a formatting issue. So, to format a number according to the ‘fr-FR’ locale, you can do:
In this setup, all my decimal values (internally) are always treated as en-GB decimals, and thus in the format I require. In other words, my application did not require the flexibility of being able to change the settings that apply to the entire current thread; rather just the opposite: I only cared about formatting the values differently.