Omar Martinez Omar Martinez - 2 months ago 19
C# Question

Decimal.Parse strange behavior on Chrome and Firefox

In a MVC project, I have a variable set in the web.Config of my project like this:

enter image description here

Then in my code, I get that variable and parse it as decimal:

enter image description here

enter image description here

As you can see, this works fine, the problem is that when I run my code on Google Chrome or Mozilla Firefox, I have diferent results:

enter image description here

enter image description here

I dont undestand why that happens, as not happen in all machines that run the web on Chrome, all I can think is that it seems to be something on the browser config but its a standard instalation, nothing different.

Anyone can point me in the right direction? Or has an idea of what can be causing this behavior?


Code in text (I don't know why, but ok)

For easy-debugging I have this:

public static decimal ServiceFee
var webConfigVar = ConfigurationManager.AppSettings["ServiceFee"];
decimal webConfigVarDecimal = decimal.Parse(webConfigVar ?? "0");
return webConfigVarDecimal;

Normally, is like this

public static decimal ServiceFee
return decimal.Parse(ConfigurationManager.AppSettings["ServiceFee"] ?? "0");

And the Web.Config

<add key="ServiceFee" value="0.024" />


I know that the code run on the server, but the only difference is the Browser, and its always with those browsers on a few machines.

No matter if the server is running local or on production

Dai Dai

Decimal.Parse uses the CultureInfo of the current request request-handling thread, which ASP.NET can (though not by default) set according to the browser's Accept header - so that browsers set to French or German will use their formatting rules (where comma ',' is the radix place, not a dot '.'). This is probably what's happening: your Chrome browser is set to use a different culture.

The fix is to specify CultureInfo.InvariantCulture when calling any Parse or ToString method if it is interacting with human-readable text (e.g. when loading a config file).

This is why static analysis is important (the "Analyze" menu in Visual Studio) - it can point out these bugs.

(My own personal opinion is that the Parse method should be removed from .NET and replaced with explicit ParseFormatted(IFormatProvider, String) and ParseInvariant(String) - but that's just me :)

I note that is inefficient to always call Parse in your property-getter. You should just cache it statically (using the new C# 6.0 read-only property syntax):

using System.Globalization;

public static decimal ServiceFee { get; } =
            ConfigurationManager.AppSettings["ServiceFee"] ?? "0",

If you do this frequently you might want a reusable method:

public static Decimal GetAppSettingDecimal(String name) {

    String textualValue = ConfigurationManager.AppSettings[ name ];
    Decimal ret;
    return Decimal.TryParse( textualValue, NumberStyles.Number, CultureInfo.InvariantCulture, out ret ) ? ret : 0;

public static Decimal ServiceFee { get; } = GetAppSettingDecimal("ServiceFee");