Search code examples
asp.net-mvc-3model-validationrequest-validation

How to handle ASP.NET MVC3 Request Validation exceptions as model or property validation errors


My question is hopefully pretty straight forward. Upon submitting my form, I would like to flag all properties (fields) that have invalid characters (specifically HTML) as model errors. The issue I am facing is that Request Validation kicks in before model binding/validation and I get HTTP 500... I saw a similar question that advertises either using [AllowHtml] property attribute on your Model/ViewModel or using <httpRuntime requestValidationMode="2.0" /> in web.config, but what I am looking for is how to "globally catch Request Validation exceptions and show them as model errors". Furthermore, I don't want to "strip" HTML tags, I want to notify the user that their input is not valid.

I thought about using Regular Expression validation attributes to find bad input, but as I mentioned, the Request Validation on ASP.NET MVC3 occurs before model binding/validation, so that is a no-go...

A really good overview of the Request Validation can be found here.


Solution

  • I think your only intention is to get the Request Validation exception during model binding and show the errors as model state error. Here is the sample,

        using System.Web.Helpers;
        public class MyModelBinder : DefaultModelBinder
        {
            public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
            {
                try
                {
                    return base.BindModel(controllerContext, bindingContext);
                }
                catch(HttpRequestValidationException ex)
                {
                    var modelState = new ModelState();
                    modelState.Errors.Add(ex.Message);
                    var key=bindingContext.ModelName;
                    var value = controllerContext.RequestContext.HttpContext.Request.Unvalidated().Form[key];
                    modelState.Value = new ValueProviderResult(value, value,CultureInfo.InvariantCulture);
                    bindingContext.ModelState.Add(key, modelState);
                }
                return null;
            }
        }
    
        protected void Application_Start()
        {
            AreaRegistration.RegisterAllAreas();
            ModelBinders.Binders.DefaultBinder = new MyModelBinder();
        }
    

    This will add the exception of only request validation in model state. Sorry, If I don't understand your question clearly.