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:
<globalization culture="auto" enableClientBasedCulture="true"/>
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:
- Set culture="auto" to culture="en-GB" in web.config.
- Use Decimal.ToString("c", ni) - where 'ni' is custom NumberFormatInfo class.
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:
NumberFormatInfo ni = Globalization.CultureInfo.GetCultureInfo("fr-FR").NumberFormat;
Decimal.ToString("c", ni);
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.