Wednesday, May 18, 2011

How to solve decimal binding problem in ASP.NET MVC

http://digitalbush.com/2011/04/24/asp-net-mvc3-json-decimal-binding-woes/



Phil Haack to the rescue! After doing some searching I stumbled across this post which fixes binding to string values with comma separators. It solves the same problem I'm having, so I'll repost the bits here:
using System;
using System.Globalization;
using System.Web.Mvc;
public class DecimalModelBinder : IModelBinder {
    public object BindModel(ControllerContext controllerContext,
                                    ModelBindingContext bindingContext) {
        ValueProviderResult valueResult = bindingContext.ValueProvider
            .GetValue(bindingContext.ModelName);
        ModelState modelState = new ModelState { Value = valueResult };
        object actualValue = null;
        try {
            actualValue = Convert.ToDecimal(valueResult.AttemptedValue,
                CultureInfo.CurrentCulture);
        }
        catch (FormatException e) {
            modelState.Errors.Add(e);
        }

        bindingContext.ModelState.Add(bindingContext.ModelName, modelState);
        return actualValue;
    }
}
Then stick this into your Global.asax.cs Application_Start:
protected void Application_Start() {
    ModelBinders.Binders.Add(typeof(decimal), new DecimalModelBinder());
    // Your other stuff goes here.
}
Once I did that and re-ran the code above, everything works as expected. See for yourself:

Model values after adding DecimalModelBinder

1 comment:

  1. I have a situation where valueResult is null, so in the try block, referencing valueResult.AttemptedValue throws an NullReferenceException, not a FormatException so the exception is not caught. I changed it to catch Exception instead of FormatException. Probably not the best practice, but it works now.

    ReplyDelete