Accepter la virgule et le point comme séparateur décimal [dupliquer]
cette question a déjà une réponse ici:
- comment définir les séparateurs décimaux dans ASP.NET les contrôleurs MVC? 4 réponses
Model binding in ASP.NET MVC est génial, mais il suit les paramètres locaux. Dans ma locale décimal separator est virgule ( ' ,'), Mais les utilisateurs utilisent point ('.') trop, parce qu'ils sont paresseux pour changer de présentation. Je veux que cela soit implémenté en un seul endroit pour tous les champs decimal
de mes modèles.
dois-je implémenter mon propre fournisseur de valeur (ou un classeur de modèle d'événement) pour le type decimal
ou Ai-je manqué une façon simple de le faire?
4 réponses
la manière la plus propre est de mettre en œuvre votre propre modèle de liant
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
}
}
et l'enregistrer à L'intérieur de Application_Start ():
ModelBinders.Binders.Add(typeof(decimal), new DecimalModelBinder());
ModelBinders.Binders.Add(typeof(decimal?), new DecimalModelBinder());
crédits: défaut ASP.NET MVC 3 model binder doesn't bind decimal properties
pour manipuler correctement le séparateur de groupe, il suffit de remplacer
Convert.ToDecimal(valueProviderResult.AttemptedValue);
dans la réponse choisie avec
Decimal.Parse(valueProviderResult.AttemptedValue, NumberStyles.Currency);
grâce à la réponse acceptée j'ai fini avec l'implémentation suivante pour gérer float, double et décimal.
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;
}
ensuite, vous avez juste à régler vos relieurs Models sur Application_Start
méthode
ModelBinders.Binders[typeof(float)] = new SingleModelBinder();
ModelBinders.Binders[typeof(double)] = new DoubleModelBinder();
ModelBinders.Binders[typeof(decimal)] = new DecimalModelBinder();
var nfInfo = new System.Globalization.CultureInfo(lang, false)
{
NumberFormat =
{
NumberDecimalSeparator = "."
}
};
Thread.CurrentThread.CurrentCulture = nfInfo;
Thread.CurrentThread.CurrentUICulture = nfInfo;