2015-05-06 7 views
8

Sto riscontrando un problema piuttosto interessante con la gestione personalizzata delle pagine di errore per una nuova applicazione ASP.NET MVC.ASP.NET MVC La pagina CustomError non viene visualizzata per alcuni dei 400 errori

Questo problema è come questo:
- se sto chiamando un URL (non importa quale) con un argomento "cattivo" alla fine della URL, come ..../c<, l'applicazione visualizza l'errore server corretto pagina come indicato nel web.config;
- se sto cambiando l'URL con uno più cattivo, come .../<c (per sembrare più simile a un tag HTML, non c'è più la pagina di errore del server visualizzata nel browser e invece di quello, sto ottenendo un semplice YSOD con un messaggio come An exception occurred while processing your request. Additionally, another exception occurred while executing the custom error page for the first exception. The request has been terminated.

secondo ELMAH, entrambe le richieste si è conclusa con un codice 400 di stato e il messaggio di essere:
- per il primo: System.Web.HttpException (0x80004005): A potentially dangerous Request.Path value was detected from the client (<). at System.Web.HttpRequest.ValidateInputIfRequiredByConfig() at System.Web.HttpApplication.PipelineStepManager.ValidateHelper(HttpContext context)
- per il secondo: System.Web.HttpException (0x80004005): A potentially dangerous Request.Path value was detected from the client (<). at System.Web.HttpRequest.ValidateInputIfRequiredByConfig() at System.Web.HttpApplication.PipelineStepManager.ValidateHelper(HttpContext context)

Quindi, entrambi gli errori sono gli stessi, il codice di stato è lo stesso, ma per uno degli errori, la pagina di errore personalizzata non è getti visualizzato. Sono anche andato su global.asax in modalità debug e controllato lo Server.GetLastError() in protected void Application_Error(object sender, EventArgs e) e ancora, entrambi gli errori erano gli stessi, niente è diverso.

In web.config, questo è come la mia tag <customErrors> assomiglia:

<customErrors mode="On" defaultRedirect="/ServerError.aspx" redirectMode="ResponseRewrite"> <error statusCode="500" redirect="/ServerError.aspx" /> <error statusCode="404" redirect="/PageNotFound.aspx" /> </customErrors>

Può per favore qualcuno mi dica il motivo per cui il comportamento è diverso in questi due casi?

Grazie mille per il vostro tempo.

+0

Su cosa stai organizzando? Cassini? IIS6? IIS7 +? –

+0

IIS 8.5 (Windows 8.1) e anche Sito Web di Azure. – Edi

risposta

12

C'è un sacco di disinformazione e/o soluzioni obsolete per la gestione degli errori in IIS 7+. Le cose principali da capire sono: -

  • .NET 4.0 ha apportato modifiche alla convalida delle richieste di ASP.NET.
  • IIS 7+ ha introdotto un nuovo modo di gestire le pagine di errore personalizzate.

maggior parte delle persone utilizzano le soluzioni miscuglio che coinvolgono tutti customErrors, httpErrors il gestore Application_Error, e spesso l'impostazione requestValidationMode="2.0" sulla proprietà httpRuntime e/o la disattivazione richiesta di convalida del tutto! Questo rende davvero difficile utilizzare le soluzioni di altre persone perché tutte e tutte queste possono influenzare il comportamento. Ho fatto una rapida ricerca e ho trovato molti semi-duplicati senza risposte accettate, probabilmente per questo motivo.

La ragione per cui questi due errori danno un comportamento diverso è che si verificano a diverse fasi nella pipeline di richieste. Il nodo customErrors nel proprio web.config interagisce con gli errori "all'interno di" dell'applicazione, mentre la convalida della richiesta ha luogo "all'esterno" dell'applicazione. IIS rifiuta la richiesta pericolosa prima del e arriva al codice dell'applicazione, quindi la sostituzione dello customErrors non avviene.

Quindi come lo ripariamo?

Idealmente si desidera una soluzione con il minor numero di parti mobili possibile. IIS7 ci offre un nuovo modo per specificare la sostituzione della pagina di errore a livello di IIS anziché a livello di applicazione: il nodo httpErrors. Questo ci permette di catturare tutti i nostri errori in un unico luogo: -

<configuration> 
    ... 
    <system.webServer> 
    ... 
    <httpErrors errorMode="Custom" existingResponse="Replace"> 
     <clear /> 
     <error statusCode="400" responseMode="ExecuteURL" path="/ServerError.aspx"/> 
     <error statusCode="403" responseMode="ExecuteURL" path="/ServerError.aspx" /> 
     <error statusCode="404" responseMode="ExecuteURL" path="/PageNotFound.aspx" /> 
     <error statusCode="500" responseMode="ExecuteURL" path="/ServerError.aspx" /> 
    </httpErrors> 
    ... 
    </system.webServer> 
    ... 
</configuration> 

Se avete a cuore di SEO (! E si dovrebbe), si devono ancora fare in modo che il controller/pagina imposta un codice di stato appropriato: -

this.Response.StatusCode = 500; // etc. 

È necessario rimuovere completamente il nodo customErrors. Viene normalmente utilizzato per retrocompatibilità. È inoltre necessario assicurarsi che requestValidationMode sia non impostato sul nodo httpRuntime.

Questo dovrebbe prendere maggior parte degli errori

correlate (ad esclusione, ovviamente, errori nel parsing web.config!): - ASP.NET MVC Custom Errors

MSDN documentazione: - http://www.iis.net/configreference/system.webserver/httperrors

Nota: nel tuo caso, se si desidera impostare defaultPath sul nodo httpErrors, si verificherà una violazione di blocco a causa delle impostazioni ApplicationHost.config. È possibile fare come ho fatto io e appena impostato path individualmente per i codici di errore che ti interessano, o si può avere uno sguardo a sbloccare il nodo: -

Il mio intuito è che è più un problema che non ne vale la pena in ambienti a basso controllo come Azure App Service/Azure Web Sites. Si potrebbe anche impostare i percorsi per i singoli codici di stato.

Ho messo un full working example of using httpErrors for custom error pages up on github. Puoi anche see it live on azure web sites.

+0

Questa è di gran lunga la risposta più dettagliata e perfetta che ho visto da anni. Grazie mille!!! Funziona perfettamente !!! – Edi

+0

Sono tornato con un'altra domanda: sembra che io abbia configurato nel mio web.config un HttpModule (ImageProcessorModule) che intercetta tutte le mie chiamate (è abbastanza normale) ma quando ho a che fare con 'Una richiesta potenzialmente pericolosa. Il valore di RawUrl è stato rilevato dal client', vedo l'errore nel testo in chiaro e non compare la pagina di 500 errori personalizzati; tuttavia, se sto commentando questo modulo per non intercettare le richieste, vedo la pagina di errore personalizzata ... Cosa mi manca? Perché il sistema non visualizza il messaggio di errore personalizzato sebbene web.config lo dica ?! Grazie mille!!! – Edi

+0

Potrebbe essere la cosa migliore da postare come una domanda separata con maggiori informazioni. Sono a conoscenza di casi in cui i bug in httpModules hanno causato problemi con errori personalizzati, ma avrei avuto bisogno di altro prima di poterlo restringere. –

Problemi correlati