asp.net-mvc 接受逗号和点作为小数点分隔符

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/14400643/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-08 02:33:11  来源:igfitidea点击:

Accept comma and dot as decimal separator

asp.net-mvcmodelbindersvalue-provider

提问by artvolk

Model binding in ASP.NET MVC is great, but it follows locale settings. In my locale decimal separator is comma (','), but users use dot ('.') too, because they are lazy to switch layouts. I want this implemented in one place for all decimalfields in my models.

ASP.NET MVC 中的模型绑定很棒,但它遵循区域设置。在我的语言环境中,十进制分隔符是逗号 (','),但用户也使用点 ('.'),因为他们懒得切换布局。我希望decimal在我的模型中的所有字段的一个地方实现这一点。

Should I implement my own Value Provider (or event Model Binder) for decimaltype or I've missed some simple way to do this?

我应该为decimal类型实现我自己的值提供程序(或事件模型绑定器)还是我错过了一些简单的方法来做到这一点?

回答by mathieu

Cleanest way is to implement your own model binder

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

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
    }    
}

And register it inside Application_Start():

并在 Application_Start() 中注册它:

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

Credits : Default ASP.NET MVC 3 model binder doesn't bind decimal properties

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

回答by Miguel Veloso

To properly handle group separator, just replace

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

Convert.ToDecimal(valueProviderResult.AttemptedValue);

in selected answer with

在选定的答案中

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

回答by labilbe

Thanks to accepted answer I ended up with the following implementation to handle float, double and decimal.

感谢接受的答案,我最终得到了以下实现来处理浮点数、双精度数和十进制数。

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;
}

Then you just have to set your ModelBinders on Application_Startmethod

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

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

回答by Denis

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