4

我对.NET 和使用十进制类型有一些奇怪的问题。我的 Web 应用程序使用以下全球化设置:

<globalization culture="auto" enableClientBasedCulture="true"/>

考虑到这一点,请考虑以下内容:十进制值 123.00 变为 GBP 123.00 英镑和 EUR 123,00(注意逗号)。当我想从十进制值 123,00 (EUR) 再次回到 GBP 时,我遇到的问题出现了,因为它变成了 123,000 - 这是一个大问题。

在这种情况下,我的应用程序已根据检测到的文化查阅查找表,并以该货币显示价格。只有当用户做出选择并且数据准备好发送到我们的支付网关时才会出现问题,这会将 123,00 欧元转换为 123,000 欧元。

有什么想法可以克服这个问题吗?

4

4 回答 4

1

也许这可以帮助你

        NumberFormatInfo ni = new NumberFormatInfo();
        ni.NumberDecimalSeparator = '.';

用法即

        Double.Parse(MyString, ni)

-雷特

不知道有什么更好的方法来检测格式,但是看看这个

    static void Main(string[] args)
    {
        // German Format (EUR)
        CultureInfo ci_de = new CultureInfo("de-DE");

        // English Format (GBP)
        CultureInfo ci_gb = new CultureInfo("en-GB");


        string test_de = "1.234.567.890,12";
        string test_en = "1,234,567,890.12";

        double result_de = 0.0;
        double result_en = 0.0;

        try
        {
            result_de = Double.Parse(test_en, ci_de.NumberFormat);
        }
        catch (FormatException ex)
        {
            Console.WriteLine("Number isn't a german format " + ex.InnerException);
        }
        try
        {
            result_en = Double.Parse(test_en, ci_gb.NumberFormat);
        }
        catch (FormatException ex)
        {
            Console.WriteLine("Number isn't a english format " + ex.InnerException);
        }

        Console.WriteLine(result_de.ToString());
        Console.WriteLine(result_en.ToString());

        Console.ReadLine();
    }
于 2009-05-22T10:52:51.107 回答
1

十进制数据类型基本上只包含一个数字——没有隐式应用于它的格式。数字的值不会因为它以不同的格式显示而改变。

很可能,您可能遇到的问题是,当您从网页接收作为字符串的输入时,您正在错误地解析它。

于 2009-05-22T12:38:36.323 回答
1

感谢所有提供经验和建议的人。

实现一个自定义类型/结构来保存我自己的 Decimal 值并不是我真正想要的,也不会真正给我所需的功能(我已经可以以适当的本地货币/格式显示十进制值,我只是无法在需要时将它们转换回英国格式)。

问题是网络配置中的这一行:

<globalization culture="auto" enableClientBasedCulture="true"/>

设置culture = "auto" 允许.NET 根据浏览器提供的值设置区域设置(顺便说一下,根据MSDN,'enableClientBasedCulture' 没有实现——所以你可以省略它)。因此,如果来自法国的访问者(在他们的浏览器中配置了语言“fr-FR”)访问了我们的网站,所有数字格式都可以正常工作(正确的小数分隔符和货币符号),但我稍后在尝试时会遇到问题将该数字从它的欧洲格式转换为我需要的英国/美国格式。

这很奇怪,但是将“123.00”转换为“fr-FR”语言环境会产生 FormatException,因为“123.00”在法语语言环境中无效(它需要“123,00”)。但是,将“123,00”(fr-FR)转换为英国/美国“en-GB”或“en-US”格式不会产生错误,而是将值变为“123,000”。我相信这应该抛出一个 FormatException 因为添加另一个零是不可接受的。

我实施的解决方案如下:

  1. 在 web.config 中将culture="auto" 设置为culture="en-GB"。
  2. 使用 Decimal.ToString("c", ni) - 其中 'ni' 是自定义 NumberFormatInfo 类。

由于我现有的代码连接到我们的数据源以根据国家/地区检索正确的十进制值,因此我现在所拥有的只是一个格式问题。因此,要根据“fr-FR”区域设置格式化数字,您可以执行以下操作:

NumberFormatInfo ni = Globalization.CultureInfo.GetCultureInfo("fr-FR").NumberFormat;
Decimal.ToString("c", ni);

在这个设置中,我所有的十进制值(内部)总是被视为 en-GB 小数,因此是我需要的格式。换句话说,我的应用程序不需要能够更改应用于整个当前线程的设置的灵活性;而恰恰相反:我只关心以不同的方式格式化值。

于 2009-05-26T11:06:56.367 回答
0

rAyt 提供了一个良好的开端,但如果您正在使用多种文化,那么自动检测十进制数是哪种文化可能会变得非常困难。为确保您始终了解,最好围绕包含文化的小数创建一个简单的包装器类型。您需要更新数据存储以存储文化代码(即 en-US),以便在重构数据时不会“忘记”数据保存为哪种文化。您拥有的任何实体都将使用您的十进制包装类型,而不是直接使用十进制,并且该类型可以具有覆盖的 ToString 方法以自动以正确的格式呈现:

public struct CulturedDecimal
{
    public decimal Value;
    public CultureInfo Culture;

    public override ToString()
    {
        return Value.ToString(Culture);
    }
}

public class SomeEntity
{
    public int ID { get; set; }
    public CulturedDecimal MonetaryValue { get; set; } // Was 'decimal' before
}
于 2009-05-23T19:11:23.530 回答