Chrome和Firefox上的Decimal.Parse奇怪行为 [英] Decimal.Parse strange behavior on Chrome and Firefox

查看:188
本文介绍了Chrome和Firefox上的Decimal.Parse奇怪行为的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在MVC项目中,我在我的项目的web.Config中设置了一个变量集,如下所示:





正如你所看到的,这个工作正常,问题是当我在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>这是为什么静态分析很重要(Visual Studio中的分析菜单) - 它可以指出这些错误。

$ b



$ b

(我个人认为应该从.NET中删除 Parse 方法,并用明确的 ParseFormatted( IFormatProvider,String) ParseInvariant(String) - 但那只是我:)

我注意到在你的属性获取器中总是调用 Parse 是低效的。您应该静态缓存它(使用新的C#6.0只读属性语法):

使用System.Globalization;使用System.Globalization;

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆