Custom Model Binder for decimals and integer: How to get the string value before MVC and do a smarter conversion

前端 未结 3 1142
时光说笑
时光说笑 2021-01-20 04:54

I want to extend the default model binding to be more smart when dealing with numbers. The default works very bad when are commas and decimals points in the game.

I

相关标签:
3条回答
  • 2021-01-20 05:00

    What about this?

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

    And a custom binder. I guess I don't know if you can override decimal binding in this way, but it works for my own types.

    public class DecimalModelBinder : DefaultModelBinder
    {
        public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
        {
            var valueProviderResult = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);
            if (valueProviderResult == null)
            {
                return base.BindModel(controllerContext, bindingContext);
            }
            // to-do: your parsing (get the text value from valueProviderResult.AttemptedValue)
            return parsedDecimal;
        }
    }
    
    0 讨论(0)
  • 2021-01-20 05:01

    The method you are probably looking for is BindModel. Here's a high level overview of how the default model binder works, suppose you have the following class:

    public class MyModel
    {
      public int Id;
      public string Name;
    }
    

    When MVC tries to bind data to MyModel, it calls BindModel on the default model binder. That binder determines that MyModel is not a "simple" data type (i.e. int, decimal, string etc). It then pulls out the possible members that it can bind to, then finds the correct model binder for each of those types and calls that model binder's BindModel method against the field/property, so model binding of a complex type is really a recursive call.

    Normally I would suggest writing a model binder just for decimal and setting that as the model binder for that data type, but I've heard others have had issue with that (I haven't tried it myself). So I would try that first, and if that doesn't work, then just check for that model type in the BindModel method of your default model binder and handle that special case.

    This is an extremely high level overview of model binding and wouldn't even begin to suggest that it's everything you need to know about how that area works.

    0 讨论(0)
  • 2021-01-20 05:19

    I'm adding an additional answer because Phil Haack blogged recently on exactly how to do this. He warns that it is untested, but he makes use of the ModelState and adds an error if needed, which is something I was never aware of when/how to do, so it was helpful to me.

    Here's a link to his post: http://haacked.com/archive/2011/03/19/fixing-binding-to-decimals.aspx

    0 讨论(0)
提交回复
热议问题