tags:

views:

34

answers:

2

We have a large ASP.NET MVC project where all numbers output to the screen are formatted as currency (i.e. ToString("c"). However, negative numbers are showing up with ()'s. For example:

decimal d = -8.88m;
Console.WriteLine(d.ToString("c"));
//outputs $(8.88)

This is a bit annoying to our users, particularly since there are in textboxes. We have a few thousand places where we send currency fields to the screen like this, so we'd love a way to change the formatting globally. Is there one? All the methods I've seen indicate that you have to create a new formatter, similar to this:

 string curCulture = System.Threading.Thread.CurrentThread.CurrentCulture.ToString();
 System.Globalization.NumberFormatInfo currencyFormat =
     new System.Globalization.CultureInfo(curCulture).NumberFormat;
 currencyFormat.CurrencyNegativePattern = 1;

We'd prefer not to change all of our ToString("c") methods ... is there a better way? My first thought was to just change our locale to Australia, but realized the date formatting would be screwed up.

+2  A: 

You are in the right track. But instead of creating a new formatter, change current thread's negative format:

  // update: dont use this!
  Thread.CurrentThread.CurrentCulture.NumberFormat.CurrencyNegativePattern = 1;

You can put this when the request is initiated and in ASP.NET one and only one thread is responsible for handling a request so this will affect all your currency formattings (unless you yourself create a new thread in which case you have the option to change it).

Update

Yes above does not work because it is read-only! try this:

            Console.WriteLine((-111.98).ToString("c"));
            CultureInfo currentCulture = Thread.CurrentThread.CurrentCulture;
            CultureInfo newCulture = new CultureInfo(currentCulture.IetfLanguageTag);
            newCulture.NumberFormat.CurrencyNegativePattern = 1;
            Thread.CurrentThread.CurrentCulture = newCulture;
            Console.WriteLine((-111.98).ToString("c"));
Aliostad
I was excited, but this didn't work - I received an InvalidOperationException ... "Instance is readonly"
Jess
HI Jess, I actuallty did not try it and I had a suspicion something in the line will be read only. see my update.
Aliostad
Yep, that works. I marked the other person's answer as correct since he was first though.
Jess
+1  A: 

Aliostad was close ... try this in your base controller:

        System.Globalization.CultureInfo modCulture = new System.Globalization.CultureInfo("en-US");
        modCulture.NumberFormat.CurrencyNegativePattern = 1;
        Thread.CurrentThread.CurrentCulture = modCulture;
It worked! Thanks!
Jess