Chrome和Firefox上的Decimal.Parse奇怪行为 [英] Decimal.Parse strange behavior on Chrome and Firefox
问题描述
正如你所看到的,这个工作正常,问题是当我在Google Chrome或Mozilla Firefox上运行我的代码时,我有不同的结果:
https://i.stack.imgur.com/jjaV7.pngrel =nofollow noreferrer>
我不明白为什么会发生这种情况,因为所有在Chrome上运行Web的机器都没有发生这种情况,我只能想到,它似乎是浏览器配置中的一些东西,但它是标准安装,没什么不同。 b
$ b
任何人都可以将我指向正确的方向?或者有什么可以导致这种行为的想法?
更新:
在文本中的代码(我不知道为什么,但确定)
为了便于调试,我有这个:
public static decimal ServiceFee
{
get
{
var webConfigVar = ConfigurationManager.AppSettings [服务费];
十进制webConfigVarDecimal = decimal.Parse(webConfigVar ??0);
返回webConfigVarDecimal;
通常,就像这样
public static decimal ServiceFee
{
get
{
return decimal .Parse(ConfigurationManager.AppSettings [ServiceFee] ??0);
}
}
和Web.Config
< appSettings>
< add key =ServiceFeevalue =0.024/>
< / appSettings>
更新2
我知道代码在服务器上运行,但唯一的区别是浏览器,并且它总是在几台机器上使用这些浏览器。
无论服务器是在本地运行还是在生产环境中 $ c> Decimal.Parse 使用当前请求请求处理线程的 CultureInfo
,ASP.NET可以(但不默认)设置根据浏览器的 Accept
标头 - 这样设置为法语或德语的浏览器将使用它们的格式规则(其中逗号','
是基数位置,而不是点'。'
)。这可能是发生了什么事:您的Chrome浏览器被设置为使用不同的文化。
修正是指定 CultureInfo.InvariantCulture $ c如果它正在与人类可读的文本进行交互(例如,当加载一个
$ b
(我个人认为应该从.NET中删除 Parse
方法,并用明确的 ParseFormatted( IFormatProvider,String)
和 ParseInvariant(String)
- 但那只是我:)
我注意到在你的属性获取器中总是调用 Parse
是低效的。您应该静态缓存它(使用新的C#6.0只读属性语法):
public static decimal ServiceFee {get; } =
Decimal.Parse(
ConfigurationManager.AppSettings [ServiceFee] ??0,
NumberStyles.Number,
CultureInfo.InvariantCulture
);
如果您经常这样做,您可能需要一种可重复使用的方法:
public static Decimal GetAppSettingDecimal(String name){
String textualValue = ConfigurationManager.AppSettings [name];
小数ret;
返回Decimal.TryParse(textualValue,NumberStyles.Number,CultureInfo.InvariantCulture,out ret)? ret:0;
}
public static Decimal ServiceFee {get; } = GetAppSettingDecimal(ServiceFee);
In a MVC project, I have a variable set in the web.Config of my project like this:
Then in my code, I get that variable and parse it as decimal:
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:
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?
UPDATE:
Code in text (I don't know why, but ok)
For easy-debugging I have this:
public static decimal ServiceFee
{
get
{
var webConfigVar = ConfigurationManager.AppSettings["ServiceFee"];
decimal webConfigVarDecimal = decimal.Parse(webConfigVar ?? "0");
return webConfigVarDecimal;
}
}
Normally, is like this
public static decimal ServiceFee
{
get
{
return decimal.Parse(ConfigurationManager.AppSettings["ServiceFee"] ?? "0");
}
}
And the Web.Config
<appSettings>
<add key="ServiceFee" value="0.024" />
</appSettings>
UPDATE 2
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
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; } =
Decimal.Parse(
ConfigurationManager.AppSettings["ServiceFee"] ?? "0",
NumberStyles.Number,
CultureInfo.InvariantCulture
);
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");
这篇关于Chrome和Firefox上的Decimal.Parse奇怪行为的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!