Using MVC ModelBinders to filter post values before binding
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 开发者_JAVA技巧value to filter it out to an empty string before the default binding happens.
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);
}
...
精彩评论