Как я могу переопределить форматирование валюты для текущей культуры для веб-приложения ASP.NET? - PullRequest
3 голосов
/ 26 августа 2011

Десятичный разделитель и тысяча разделителей для региона en-ZA - это ',' и '' соответственно, но обычно используются разделители '.' для десятичной, плюс мой пользователь хочет ',' для разделителя тысяч. Я хочу установить их глобально, чтобы мне приходилось использовать только строку формата {0:C} для всех моих полей валюты, без каких-либо явных вызовов Format или ToString.

Я бы предпочел иметь возможность делать это без изменения настроек культуры на веб-сервере, поскольку мне также нужно установить десятичные разряды для валюты на ноль, так как центы не нужны при составлении отчетов по оценкам R100k и выше и т. Д. Я не хотел бы произвольно устанавливать всю культуру на ноль мест, только один для этого приложения.

В комментариях к своему ответу по на этот вопрос Джон Скит предлагает клонировать текущую культуру и настройки и изменить необходимые настройки. Я сделал это следующим образом:

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

Однако, как мне активировать эту новую культуру для всех запросов, которые приложение обрабатывает с этого момента? Есть ли другой способ достичь того, что я хочу сделать?

Ответы [ 2 ]

3 голосов
/ 26 августа 2011

Вы можете использовать событие 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;
0 голосов
/ 27 августа 2011

Задав много вопросов и проведя много экспериментов, я решил, что можно с уверенностью утверждать, что единственный способ сделать это - использовать элементы управления, полученные из готовых элементов управления, и выполнить свое собственное форматирование с использованием настроенного объекта культуры. Получите свой контроль, например, от 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);
    }
}

Я опубликую статью позже со всеми кровавыми подробностями.

...