Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I override RequestValidation in ASP.NET WebAPI

I'm having problems with requests that include 'dangerous characters' as part of a Web API URL. The Url includes an & which is properly Url encoded, but still causes a Request Validation ASP.NET error.

Unlike MVC there appears to be no [ValidateInput(false)] attribute to force and disable this functionality.

like image 705
Rick Strahl Avatar asked Mar 14 '12 08:03

Rick Strahl


People also ask

How does Web API handle validation errors?

Handling Validation Errors Web API does not automatically return an error to the client when validation fails. It is up to the controller action to check the model state and respond appropriately. If model validation fails, this filter returns an HTTP response that contains the validation errors.

How do I change the default validation error in ASP NET MVC?

You can set your own custom error message by using validation-message property. To display the error message, specify the corresponding annotation attribute followed by the message to display. jQuery predefined error messages to that annotation attribute will be shown when this property is not defined.


2 Answers

You can get more fine-grained control over this by setting the requestValidationType attribute of the httpRuntime element to a custom type that inherits from System.Web.Util.RequestValidator and overrides IsValidRequestString.

Unfortunately this isn't part of the WebAPI pipeline, so can't directly check for things like action filters (i.e. attributes on controller methods).

However, if you specifically care about the Validation of Form fields, the Validator doesn't get called on these until you access them, which happens after Action Filters are fired, so you can opt-out of validation using an attribute by creating classes like the following...

public class AllowFormHtmlAttribute : ActionFilterAttribute
{
    public override void OnActionExecuting(HttpActionContext actionContext)
    {
        HttpContext.Current.Items["AllowFormHtml"] = true;
    }
}

public class CustomRequestValidator : RequestValidator
{
    protected override bool IsValidRequestString(HttpContext context, string value, RequestValidationSource requestValidationSource, string collectionKey, out int validationFailureIndex)
    {
        if (context.Items["AllowFormHtml"] as bool? == true && requestValidationSource == RequestValidationSource.Form)
        {
            validationFailureIndex = 0;
            return true;
        }

        return base.IsValidRequestString(
            context, value, requestValidationSource, collectionKey, out validationFailureIndex);
    }
}

... Then just annotating your controller method with [AllowFormHtml]

However, if you're accessing form fields directly from the HttpRequest, it's simpler to use HttpRequest.Unvalidated, which bypasses validation.

like image 172
hgcummings Avatar answered Sep 30 '22 19:09

hgcummings


With RequestValidation set to 4.0 in the configuration the answer is no. You can however revert back to 2.0 Request Validation in which case the MVC attribute works as you would expect: Validate by default and explicitly override when needed.

<httpRuntime executionTimeout="300" requestValidationMode="2.0" />

Talked in detail about this and some of the options here: http://www.west-wind.com/weblog/posts/2010/Aug/19/RequestValidation-Changes-in-ASPNET-40

like image 8
Rick Strahl Avatar answered Oct 19 '22 02:10

Rick Strahl