asp.net-mvc modelbinders value-provider

asp.net mvc - Acepta la coma y el punto como separador decimal



asp.net-mvc modelbinders (4)

Esta pregunta ya tiene una respuesta aquí:

El enlace de modelo en ASP.NET MVC es excelente, pero sigue la configuración regional. En mi localidad, el separador decimal es coma ('',''), pero los usuarios también usan punto (''.''), Porque son flojos para cambiar de diseño. Quiero que esto se implemente en un solo lugar para todos decimal campos decimal en mis modelos.

¿Debo implementar mi propio Proveedor de valor (o Carpeta de modelo de evento) para tipo decimal o me he perdido alguna forma simple de hacer esto?


Gracias a la respuesta aceptada terminé con la siguiente implementación para manejar float, double y 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; }

Luego solo tiene que configurar sus ModelBinders en el método Application_Start

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


La forma más limpia es implementar su propio modelo de carpeta

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

Y registrarlo dentro de Application_Start ():

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

Créditos: el cuaderno de modelo predeterminado de ASP.NET MVC 3 no enlaza las propiedades decimales


Para manejar adecuadamente el separador de grupos, simplemente reemplace

Convert.ToDecimal(valueProviderResult.AttemptedValue);

en respuesta seleccionada con

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


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