如何覆盖ASP.NET Web应用程序的当前区域性的货币格式?

时间:2011-08-26 07:46:51

标签: .net asp.net internationalization formatting cultureinfo

en-ZA区域的货币十进制和千位分隔符分别是','和'',但常用的分隔符是'。'对于十进制,加上我的用户想要','为千位分隔符。我希望在全球范围内设置这些内容,这样我只需对所有货币字段使用{0:C}格式字符串,而无需进行任何明确的FormatToString调用。

我希望能够在不更改Web服务器上的文化设置的情况下执行此操作,因为我还需要将货币的小数位设置为零,因为在报告R100k及以上的估计值时不需要分数我不想随意将整个文化设置为零,只有一个用于此应用程序。

在对this question的答案的评论中,Jon Skeet建议克隆当前的文化,设置和更改所需的设置。我这样做了如下:

void Application_Start(object sender, EventArgs e)
{
    var newCulture = (CultureInfo)CultureInfo.CurrentCulture.Clone();
    newCulture.NumberFormat.CurrencyDecimalSeparator = ".";
    newCulture.NumberFormat.CurrencyGroupSeparator = ",";
}

但是,如何为此应用程序处理的所有请求激活新文化?还有另一种方法可以达到我想做的目的吗?

2 个答案:

答案 0 :(得分:3)

您可以使用Application_BeginRequest事件为每个请求设置文化。内幕事件:

var newCulture = (CultureInfo)CultureInfo.CurrentCulture.Clone();
newCulture.NumberFormat.CurrencyDecimalSeparator = ".";
newCulture.NumberFormat.CurrencyGroupSeparator = ",";

System.Threading.Thread.CurrentThread.CurrentCulture = newCulture;
System.Threading.Thread.CurrentThread.CurrentUICulture = newCulture;

答案 1 :(得分:0)

在询问了很多问题并做了很多实验之后,我已经决定可以安全地说明这样做的唯一方法是使用从开箱即用控件派生的控件,并使用自定义的文化对象进行自己的格式化。从中获取控制权BoundField并提供您自己的FormatProvider

public class BoundReportField : BoundField
{
    protected virtual string GetDefaultFormatString(FieldFormatTypes formatType)
    {
        var prop = typeof(FormatStrings).GetProperty(formatType.ToString()).GetValue(null, null);
        return prop.ToString();
    }

    protected virtual IFormatProvider GetFormatProvider(FieldFormatTypes formatType)
    {
        var info = (CultureInfo)CultureInfo.CurrentCulture.Clone();
        info.NumberFormat.CurrencyDecimalDigits = 0;
        info.NumberFormat.CurrencySymbol = "R";
        info.NumberFormat.CurrencyGroupSeparator = ",";
        info.NumberFormat.CurrencyDecimalSeparator = ".";
        return info;
    }

    private FieldFormatTypes _formatType;
    public virtual FieldFormatTypes FormatType
    {
        get { return _formatType; }
        set
        {
            _formatType = value;
            DataFormatString = GetDefaultFormatString(value);
        }
    }

    protected override string FormatDataValue(object dataValue, bool encode)
    {
        // TODO Consider the encode flag.
        var formatString = DataFormatString;
        var formatProvider = GetFormatProvider(_formatType);
        if (string.IsNullOrWhiteSpace(formatString))
        {
            formatString = GetDefaultFormatString(_formatType);
        }
        return string.Format(formatProvider, formatString, dataValue);
    }
}

稍后我将发表一篇文章,其中包含所有血腥细节。