Question

I need to filter out some values before they are bound from POST data in MVC2. Unfortunately i can't change the client side code which is sometimes passing "N/A" for a form value that is to be mapped into decimal? type. What needs to happen is if "N/A" is the POST value blank it out before it's bound/validated.

I've tried all morning to get it working using a ModelBinder that extends the DefaultModelBinder:

public class DecimalFilterBinder : DefaultModelBinder
{
    protected override void BindProperty(ControllerContext controllerContext,
        ModelBindingContext bindingContext, PropertyDescriptor propertyDescriptor)
    {
        if (propertyDescriptor.PropertyType == typeof(decimal?))
        {
            var model = bindingContext.Model;
            PropertyInfo property = model.GetType().GetProperty(propertyDescriptor.Name);
            var httpRequest = controllerContext.RequestContext.HttpContext.Request;
            if (httpRequest.Form[propertyDescriptor.Name] == "-" ||
                httpRequest.Form[propertyDescriptor.Name] == "N/A")
            {
                property.SetValue(model, null, null);
            }
            else
            {
                base.BindProperty(controllerContext, bindingContext, propertyDescriptor);
            }
        }
        else
        {
            base.BindProperty(controllerContext, bindingContext, propertyDescriptor);
        }
    }
}

The problem I'm having is I don't know how to get access to the originally posted value when it is within a list. I can't just to Form[propertyDescriptor.Name] because it's contained within a list item in the form (so the input is really Values[0].Property1, for example). I have the model binder hooked up in global.asax and running fine, I just don't know how to get a hold of the original form value to filter it out to an empty string before the default binding happens.

Was it helpful?

Solution

Wow, the bindingContext has a ModelName property which gives you the prefix (for the list item). Using that lets me get the original form value:

...
var httpRequest = controllerContext.RequestContext.HttpContext.Request;
if (httpRequest.Form[bindingContext.ModelName + propertyDescriptor.Name] == "-" ||
    httpRequest.Form[bindingContext.ModelName + propertyDescriptor.Name] == "N/a")
{
    property.SetValue(model, null, null);
}
else
{
    base.BindProperty(controllerContext, bindingContext, propertyDescriptor);
}
...
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top