2012-03-14 4 views
11

Si verificano problemi con le richieste che includono "caratteri pericolosi" come parte di un URL dell'API Web. L'URL include uno & che è correttamente codificato Url, ma causa ancora un errore ASP.NET di convalida della richiesta.Come eseguire l'override di RequestValidation in ASP.NET WebAPI

A differenza di MVC, sembra non esserci alcun attributo [ValidateInput (false)] per forzare e disabilitare questa funzionalità.

risposta

8

Attiva la risposta è quella di farlo in web.config utilizzando:

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

È possibile impostare questa a livello globale oa livello sub-directory. È possibile sfruttare l'elemento <location path=""> per specificare questa impostazione solo sotto determinati percorsi. Ad esempio, se il percorso Web API che è stata colpita vissuto sotto api/immagini si potrebbe effettuare le seguenti operazioni:

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

Maggiori informazioni: https://msdn.microsoft.com/en-us/library/e1f13641(v=vs.100).aspx

+0

Questa è l'unica soluzione che ha funzionato per me. Aggiungendo 'requestValidationMode = '2.0'' a web.config e provando l'attributo' [ValidateInput (false)] 'sul metodo di azione NON ha funzionato.Ha iniziato a funzionare dopo aver aggiunto 'requestPathInvalidCharacters =" "'. Penso che questo sia dovuto al fatto che l'errore qui è parte della convalida Request.Path piuttosto che della convalida Request.Form. – quakkels

+0

Non ha bisogno di essere globale, basta usare l'elemento 'location' per limitare il percorso. Quindi se la tua rotta dell'API Web è in 'api/foo' puoi limitare la posizione a' path = "api/foo" 'e aggiungere lì la configurazione' httpRuntime'. Confermato funziona bene in IIS. Inoltre, MSDN dichiara esplicitamente che "" può essere "dichiarato a livello di macchina, sito, applicazione e sottodirectory". Ho aggiornato la risposta. – kamranicus

1

per @Levi nostro ragazzo Web Security:

La configurazione è l'unico modo per farlo. Anche MVC [ValidateInput (false)] non sarebbe di aiuto in questo particolare scenario.

Disattivarlo in Web.config non è necessario un'idea terribile. Se stai seguendo le buone pratiche di sicurezza convalidando e codificando i dati non fidati, è perfettamente corretto applicarli a livello di applicazione.

+0

'[ValidateInput (false)]' non funziona nel mio caso. Penso che sia perché '[ValidateInput (false)]' si riferisce al 'Request.Form' piuttosto che a 'Request.Path'. – quakkels

2

Con RequestValidation impostato su 4.0 nella configurazione, la risposta è no. È tuttavia possibile ripristinare la convalida della richiesta 2.0 nel qual caso l'attributo MVC funziona come previsto: Convalida per impostazione predefinita e sovrascrittura esplicita quando necessario.

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

parlato in dettaglio di questo e alcune delle opzioni qui: http://www.west-wind.com/weblog/posts/2010/Aug/19/RequestValidation-Changes-in-ASPNET-40

+0

Questa è l'unica opzione che ha funzionato per me. – santos

2

È possibile ottenere un controllo più granulare su questo impostando l'attributo requestValidationType dell'elemento httpRuntime ad un tipo personalizzato che eredita da System.Web.Util.RequestValidator e sostituisce IsValidRequestString.

Purtroppo questo non fa parte della pipeline WebAPI, quindi non è possibile controllare direttamente elementi come i filtri di azione (ovvero gli attributi sui metodi del controller).

Tuttavia, se si preoccupa specificamente dei campi Convalida dei moduli, il Convalida non viene richiamato fino a quando non li si accede, cosa che accade dopo l'attivazione dei filtri di azione, quindi è possibile annullare la convalida utilizzando un attributo con la creazione di classi come la seguente ...

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

... Poi basta annotare il metodo di controller con [AllowFormHtml]

Tuttavia, se si sta accedendo campi del modulo direttamente dal HttpRequest, è più semplice da usare HttpRequest.Unvalidated , che ignora la convalida.