Change default NumberStyles on integers?

£可爱£侵袭症+ 提交于 2019-12-10 13:34:50

问题


I have a model that has an integer property. When the model is submitted with 23443, the model binder works great and the value is available in the action. But if the model is submitted with a thousands separator like 23,443, the value isn't parsed and the property is zero. But I found that a property with the type of decimal could have the thousands separator and it would parse and be populated correctly.

I found out that by default Int32.Parse() doesn't parse thousands separator but Decimal.Parse() does allow thousands separator. I don't want to have to write a check like:

public ActionResult Save(Car model, FormCollection form) {
    Int32 milage;
    if(model.MyProperty == 0 && Int32.TryParse(form["MyProperty"], NumberStyles.AllowThousands, CultureInfo.InvariantCulture, out milage) {
        model.MyProperty = milage;
    } else
        ModelState.AddModelError("Invalid", "Property looks invalid");

    [...]
}

every time I deal with these fields. It looks ugly, and moves all the validation out of the model attributes. Changing the type of the property to decimal just to make the model binding work doesn't seem like a smart idea. When I look into the model binder, it looks like it's using TypeConverter to complete the conversions from string to the type. And it looks like Int32Converter uses Int32.Parse() with NumberStyles.Integer.

Is there a way to change the behavior of Int32Converter to allow the thousands separator to be parsed by default? Maybe override the default NumberStyles on Int32.Parse() across the entire app? Or is adding my own model binder which parses the integers with NumberStyles.AllowThousands the only/correct course of action?


回答1:


I think, you can add custom binder for int type.

Demo: http://dotnetfiddle.net/VSMQzw

Useful links:

  • http://haacked.com/archive/2011/03/19/fixing-binding-to-decimals.aspx/
  • Default ASP.NET MVC 3 model binder doesn't bind decimal properties
  • http://www.codeproject.com/Articles/551576/ASP-NET-MVC-Model-Binding-and-Data-Annotation

updated

Based on Haacked article:

using System;
using System.Globalization;
using System.Web.Mvc;

public class IntModelBinder : IModelBinder
{
    #region Implementation of IModelBinder

    public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) 
    {
        ValueProviderResult valueResult = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);
        ModelState modelState = new ModelState { Value = valueResult };
        bindingContext.ModelState[bindingContext.ModelName] = modelState;

        object actualValue = null;
        try 
        {
            actualValue = Int32.Parse(valueResult.AttemptedValue, NumberStyles.Number, CultureInfo.InvariantCulture);
        }
        catch (FormatException e) 
        {
            modelState.Errors.Add(e);
        }

        bindingContext.ModelState.Add(bindingContext.ModelName, modelState);
        return actualValue;
    }

    #endregion
}

And in the Application_Start event (probably in the Global.asax), add:

ModelBinders.Binders.Add(typeof(int), new IntModelBinder());


来源:https://stackoverflow.com/questions/21189158/change-default-numberstyles-on-integers

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!