接受逗号和点作为小数点分隔符[复制](Accept comma and dot as decimal

2019-07-18 09:47发布

这个问题已经在这里有一个答案:

  • 如何设置在ASP.NET MVC控制器的小数点分隔符? 4个回答

模型的ASP.NET MVC结合是伟大的,但它遵循区域设置。 在我的区域设置小数点分隔符是逗号(“‘),但用户使用点(’。”)也是如此,因为他们是懒惰的切换布局。 我想这个在一个地方实施了所有decimal在我的模型领域。

我应该实现我自己的价值提供者(或事件模型绑定) decimal型或我已经错过了一些简单的方法来做到这一点?

Answer 1:

干净的方法是实现自己的模型绑定

public class DecimalModelBinder : DefaultModelBinder
{
    public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
    {
        var valueProviderResult = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);

        return valueProviderResult == null ? base.BindModel(controllerContext, bindingContext) : Convert.ToDecimal(valueProviderResult.AttemptedValue);
        // of course replace with your custom conversion logic
    }    
}

并注册它里面的Application_Start():

ModelBinders.Binders.Add(typeof(decimal), new DecimalModelBinder());
ModelBinders.Binders.Add(typeof(decimal?), new DecimalModelBinder());

积分: 默认ASP.NET MVC 3模型绑定不绑定小数性质



Answer 2:

要正确处理组分隔符,只需更换

Convert.ToDecimal(valueProviderResult.AttemptedValue);

在选择的答案

Decimal.Parse(valueProviderResult.AttemptedValue, NumberStyles.Currency);


Answer 3:

由于接受的答案我结束了下面的实现来处理浮点,双精度和小数。

public abstract class FloatingPointModelBinderBase<T> : DefaultModelBinder
{
    protected abstract Func<string, IFormatProvider, T> ConvertFunc { get; }

    public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
    {
        var valueProviderResult = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);
        if (valueProviderResult == null) return base.BindModel(controllerContext, bindingContext);
        try
        {
            return ConvertFunc.Invoke(valueProviderResult.AttemptedValue, CultureInfo.CurrentUICulture);
        }
        catch (FormatException)
        {
            // If format error then fallback to InvariantCulture instead of current UI culture
            return ConvertFunc.Invoke(valueProviderResult.AttemptedValue, CultureInfo.InvariantCulture);
        }
    }
}

public class DecimalModelBinder : FloatingPointModelBinderBase<decimal>
{
    protected override Func<string, IFormatProvider, decimal> ConvertFunc => Convert.ToDecimal;
}

public class DoubleModelBinder : FloatingPointModelBinderBase<double>
{
    protected override Func<string, IFormatProvider, double> ConvertFunc => Convert.ToDouble;
}

public class SingleModelBinder : FloatingPointModelBinderBase<float>
{
    protected override Func<string, IFormatProvider, float> ConvertFunc => Convert.ToSingle;
}

然后,你只需要设置你的ModelBinders Application_Start方法

ModelBinders.Binders[typeof(float)] = new SingleModelBinder();
ModelBinders.Binders[typeof(double)] = new DoubleModelBinder();
ModelBinders.Binders[typeof(decimal)] = new DecimalModelBinder();


Answer 4:

var nfInfo = new System.Globalization.CultureInfo(lang, false)
{
    NumberFormat =
    {
        NumberDecimalSeparator = "."
    }
};
Thread.CurrentThread.CurrentCulture = nfInfo;
Thread.CurrentThread.CurrentUICulture = nfInfo;


文章来源: Accept comma and dot as decimal separator [duplicate]