具有货币格式值的TryUpdateModel?

时间:2009-11-22 22:05:09

标签: c# asp.net-mvc

有没有办法让UpdateModel或TryUpdateModel将货币或货币格式化的值(例如1,200.00美元)解析为小数而不会破坏大块?

3 个答案:

答案 0 :(得分:3)

答案 1 :(得分:2)

Freddy Rios已经给了答案,因为他的链接为我提供了这样做的基础,但代码需要一些修复:

   // http://www.crydust.be/blog/2009/07/30/custom-model-binder-to-avoid-decimal-separator-problems/
public class MoneyParsableModelBinder : DefaultModelBinder
{

    public override object BindModel(ControllerContext controllerContext,
      ModelBindingContext bindingContext)
    {

        object result = null;
        // Added support for decimals and nullable types - c.
        if (
            bindingContext.ModelType == typeof(double)
            || bindingContext.ModelType == typeof(decimal)
            || bindingContext.ModelType == typeof(double?)
            || bindingContext.ModelType == typeof(decimal?)
            )
        {

            string modelName = bindingContext.ModelName;
            string attemptedValue = bindingContext.ValueProvider[modelName].AttemptedValue;

            // Depending on cultureinfo the NumberDecimalSeparator can be "," or "."
            // Both "." and "," should be accepted, but aren't.
            string wantedSeperator = NumberFormatInfo.CurrentInfo.NumberDecimalSeparator;
            string alternateSeperator = (wantedSeperator == "," ? "." : ",");

            if (attemptedValue.IndexOf(wantedSeperator) == -1
              && attemptedValue.IndexOf(alternateSeperator) != -1)
            {
                attemptedValue = attemptedValue.Replace(alternateSeperator, wantedSeperator);
            }

            // If SetModelValue is not called it may result in a null-ref exception if the model is resused - c. 
            bindingContext.ModelState.SetModelValue(modelName, bindingContext.ValueProvider[modelName]);

            try
            {
                // Added support for decimals and nullable types - c.
                if (bindingContext.ModelType == typeof(double) || bindingContext.ModelType == typeof(double?))
                {
                    result = double.Parse(attemptedValue, NumberStyles.Any);
                }
                else
                {
                    result = decimal.Parse(attemptedValue, NumberStyles.Any);
                }
            }
            catch (FormatException e)
            {
                bindingContext.ModelState.AddModelError(modelName, e);
            }
        }
        else
        {
            result = base.BindModel(controllerContext, bindingContext);
        }

        return result;
    }
}

它不漂亮,但它有效。

答案 2 :(得分:1)

在调用这些方法之前,您是否能够预先解析值?如果是这样,您可以使用以下方法来执行此操作

    var provider = (NumberFormatInfo)CultureInfo.InvariantCulture.NumberFormat.Clone();
    provider.CurrencySymbol = "$";
    var x = decimal.Parse(
        "$1,200",
        NumberStyles.AllowCurrencySymbol | NumberStyles.AllowDecimalPoint | NumberStyles.AllowThousands,
        provider);