问题
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.
回答1:
Turns out the answer is to do this in web.config using:
<system.web>
<httpRuntime requestPathInvalidCharacters="" />
</system.web>
You can set this globally or at the sub-directory level. You can leverage the <location path="">
element to specify this setting only underneath certain paths. For example, if your Web API route that was affected lived underneath api/images you could do the following:
<location path="api/images">
<system.web>
<httpRuntime requestPathInvalidCharacters="" />
</system.web>
</location>
More information: https://msdn.microsoft.com/en-us/library/e1f13641(v=vs.100).aspx
回答2:
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
回答3:
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.
回答4:
per @Levi our Web Security guy:
Config is the only way to do this. Even MVC’s [ValidateInput(false)] wouldn’t help with this particular scenario.
Disabling it in Web.config isn’t necessary a terrible idea. If you’re following good security practice by validating and encoding untrusted data, it’s perfectly fine to apply it application-wide.
来源:https://stackoverflow.com/questions/9698224/how-do-i-override-requestvalidation-in-asp-net-webapi