Как переопределить RequestValidation в ASP.NET WebAPI

У меня возникают проблемы с запросами, которые включают "опасные символы" как часть URL-адреса веб-API. Url включает в себя и который правильно кодируется в Url, но все еще вызывает ошибку ASP.NET Request Validation.

В отличие от MVC не существует атрибута [ValidateInput (false)], чтобы принудительно отключить эту функцию.

Ответ 1

Выключает ответ, чтобы сделать это в web.config, используя:

<system.web>
  <httpRuntime requestPathInvalidCharacters="" />  
</system.web>

Вы можете установить это глобально или на уровне подкаталогов. Вы можете использовать элемент <location path="">, чтобы указать этот параметр только под определенными путями. Например, если ваш трафик веб-API, который был затронут, находился под api/images, вы могли бы сделать следующее:

<location path="api/images">
  <system.web>
    <httpRuntime requestPathInvalidCharacters="" />  
  </system.web>
</location>

Дополнительная информация: https://msdn.microsoft.com/en-us/library/e1f13641(v=vs.100).aspx

Ответ 2

С RequestValidation, установленным в 4.0, в конфигурации нет ответа. Тем не менее, вы можете вернуться к 2.0 Request Validation, в этом случае атрибут MVC работает так, как вы ожидали: проверять по умолчанию и явно переопределять, когда это необходимо.

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

Разговор подробно об этом и некоторых вариантах здесь: http://www.west-wind.com/weblog/posts/2010/Aug/19/RequestValidation-Changes-in-ASPNET-40

Ответ 3

Вы можете получить более мелкий контроль над этим, установив атрибут requestValidationType элемента httpRuntime на собственный тип, который наследует от System.Web.Util.RequestValidator и переопределяет IsValidRequestString.

К сожалению, это не является частью конвейера WebAPI, поэтому он не может напрямую проверять такие действия, как фильтры действий (например, атрибуты методов контроллера).

Однако, если вы специально заботитесь о полях "Проверка формы", Validator не будет вызываться на них до тех пор, пока вы не получите доступ к ним, что происходит после активации Action Filters, поэтому вы можете отказаться от проверки с помощью атрибута создавая классы, подобные следующим...

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);
    }
}

... Затем просто комментируйте свой метод контроллера с помощью [AllowFormHtml]

Однако, если вы обращаетесь к полям формы непосредственно из HttpRequest, проще использовать HttpRequest.Unvalidated, который обходит проверку.

Ответ 4

per @Levi наш парень в Интернете:

Конфигурация - единственный способ сделать это. Даже MVC [ValidateInput (false)] не поможет в этом конкретном сценарии.

Отключение его в Web.config не обязательно ужасная идея. Если вы придерживаетесь хорошей практики безопасности, проверяя и кодируя ненадежные данные, ее совершенно прекрасное применение для приложения в целом.