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?

22
demandé sur Anderson Pimentel 2013-01-18 18:09:33

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

37
répondu mathieu 2017-05-23 12:34:19

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);
5
répondu Miguel Veloso 2015-06-23 22:58:10

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();
2
répondu labilbe 2017-03-01 16:07:00
var nfInfo = new System.Globalization.CultureInfo(lang, false)
{
    NumberFormat =
    {
        NumberDecimalSeparator = "."
    }
};
Thread.CurrentThread.CurrentCulture = nfInfo;
Thread.CurrentThread.CurrentUICulture = nfInfo;
1
répondu Denis 2014-10-15 10:30:11