Gestire gli errori in ASP.NET CoreHandle errors in ASP.NET Core

Di Tom Dykstra, Luke Latham e Steve SmithBy Tom Dykstra, Luke Latham, and Steve Smith

Questo articolo descrive gli approcci comuni per la gestione degli errori nelle app ASP.NET Core.This article covers common approaches to handling errors in ASP.NET Core apps.

Visualizzare o scaricare il codice di esempio.View or download sample code. (Come scaricare un esempio.) L'articolo include istruzioni su come impostare le direttive del preprocessore (#if, #endif, #define) nell'app di esempio per abilitare scenari diversi.(How to download.) The article includes instructions about how to set preprocessor directives (#if, #endif, #define) in the sample app to enable different scenarios.

Pagina delle eccezioni per gli sviluppatoriDeveloper Exception Page

In Pagina delle eccezioni per gli sviluppatori sono disponibili informazioni dettagliate sulle eccezioni delle richieste.The Developer Exception Page displays detailed information about request exceptions. La pagina è disponibile nel pacchetto Microsoft.AspNetCore.Diagnostics che si trova nel metapacchetto Microsoft.AspNetCore.App.The page is made available by the Microsoft.AspNetCore.Diagnostics package, which is in the Microsoft.AspNetCore.App metapackage. Aggiungere codice al metodo Startup.Configure per abilitare la pagina quando l'app è in esecuzione nell'ambiente di sviluppo:Add code to the Startup.Configure method to enable the page when the app is running in the Development environment:

if (env.IsDevelopment())
{
    app.UseDeveloperExceptionPage();
}
else
{
    app.UseExceptionHandler("/Error");
    app.UseHsts();
}

Posizionare la chiamata a UseDeveloperExceptionPage prima di qualsiasi middleware in cui si vogliono rilevare le eccezioni.Place the call to UseDeveloperExceptionPage before any middleware that you want to catch exceptions.

Avviso

Abilitare la pagina delle eccezioni per gli sviluppatori solo quando l'app è in esecuzione nell'ambiente di sviluppo.Enable the Developer Exception Page only when the app is running in the Development environment. per non condividere pubblicamente le informazioni dettagliate sulle eccezioni quando l'app è in esecuzione nell'ambiente di produzione.You don't want to share detailed exception information publicly when the app runs in production. Per altre informazioni sulla configurazione di ambienti, vedere Usare più ambienti in ASP.NET Core.For more information on configuring environments, see Usare più ambienti in ASP.NET Core.

La pagina include le informazioni seguenti sull'eccezione e sulla richiesta:The page includes the following information about the exception and the request:

  • Analisi dello stackStack trace
  • Parametri della stringa di query (se presenti)Query string parameters (if any)
  • Cookie (se presenti)Cookies (if any)
  • IntestazioniHeaders

Per visualizzare la pagina delle eccezioni per gli sviluppatori nell'app di esempio, usare la direttiva del preprocessore DevEnvironment e selezionare Trigger an exception (Attiva un'eccezione) nella home page.To see the Developer Exception Page in the sample app, use the DevEnvironment preprocessor directive and select Trigger an exception on the home page.

Pagina del gestore di eccezioniException handler page

Per configurare una pagina di gestione degli errori personalizzata per l'ambiente di produzione, usare il middleware di gestione delle eccezioni.To configure a custom error handling page for the Production environment, use the Exception Handling Middleware. Il middleware:The middleware:

  • Intercetta e registra le eccezioni.Catches and logs exceptions.
  • Esegue nuovamente la richiesta in una pipeline alternativa per la pagina o il controller indicati.Re-executes the request in an alternate pipeline for the page or controller indicated. La richiesta non viene eseguita nuovamente se la risposta è stata avviata.The request isn't re-executed if the response has started.

Nell'esempio seguente UseExceptionHandler aggiunge il middleware di gestione delle eccezioni in ambienti non di sviluppo:In the following example, UseExceptionHandler adds the Exception Handling Middleware in non-Development environments:

if (env.IsDevelopment())
{
    app.UseDeveloperExceptionPage();
}
else
{
    app.UseExceptionHandler("/Error");
    app.UseHsts();
}

Il modello di app Razor Pages fornisce una pagina di errore ( .cshtml) e una classe PageModel (ErrorModel) nella cartella Pages.The Razor Pages app template provides an Error page (.cshtml) and PageModel class (ErrorModel) in the Pages folder. Per un'app MVC, il modello di progetto include un metodo di azione Error e una visualizzazione degli errori.For an MVC app, the project template includes an Error action method and an Error view. Ecco il metodo di azione:Here's the action method:

[AllowAnonymous]
public IActionResult Error()
{
    return View(new ErrorViewModel 
        { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });
}

Non decorare il metodo dell'azione di gestione degli errori con attributi di metodo HTTP, ad esempio HttpGet.Don't decorate the error handler action method with HTTP method attributes, such as HttpGet. I verbi espliciti impediscono ad alcune richieste di raggiungere il metodo.Explicit verbs prevent some requests from reaching the method. Consentire l'accesso anonimo al metodo in modo che gli utenti non autenticati possano ricevere la visualizzazione degli errori.Allow anonymous access to the method so that unauthenticated users are able to receive the error view.

Accedere all'eccezioneAccess the exception

Usare IExceptionHandlerPathFeature per accedere all'eccezione e al percorso della richiesta originale in un controller o in una pagina del gestore degli errori:Use IExceptionHandlerPathFeature to access the exception and the original request path in an error handler controller or page:

var exceptionHandlerPathFeature =
    HttpContext.Features.Get<IExceptionHandlerPathFeature>();
if (exceptionHandlerPathFeature?.Error is FileNotFoundException)
{
    ExceptionMessage = "File error thrown";
}
if (exceptionHandlerPathFeature?.Path == "/index")
{
    ExceptionMessage += " from home page";
}

Avviso

Non fornire informazioni sugli errori sensibili ai client.Do not serve sensitive error information to clients. Fornire informazioni sugli errori rappresenta un rischio di sicurezza.Serving errors is a security risk.

Per visualizzare la pagina di gestione delle eccezioni nell'app di esempio, usare le direttive del preprocessore ProdEnvironment e ErrorHandlerPage e selezionare Trigger an exception (Attiva un'eccezione) nella home page.To see the exception handling page in the sample app, use the ProdEnvironment and ErrorHandlerPage preprocessor directives, and select Trigger an exception on the home page.

Espressione lambda per il gestore di eccezioniException handler lambda

Un'alternativa a una pagina di gestione delle eccezioni personalizzata consiste nel fornire un'espressione lambda a UseExceptionHandler.An alternative to a custom exception handler page is to provide a lambda to UseExceptionHandler. L'uso di un'espressione lambda consente l'accesso all'errore prima di restituire la risposta.Using a lambda allows access to the error before returning the response.

Di seguito è riportato un esempio dell'uso di un'espressione lambda per la gestione delle eccezioni:Here's an example of using a lambda for exception handling:

if (env.IsDevelopment())
{
    app.UseDeveloperExceptionPage();
}
else
{
   app.UseExceptionHandler(errorApp =>
   {
        errorApp.Run(async context =>
        {
            context.Response.StatusCode = 500;
            context.Response.ContentType = "text/html";

            await context.Response.WriteAsync("<html lang=\"en\"><body>\r\n");
            await context.Response.WriteAsync("ERROR!<br><br>\r\n");

            var exceptionHandlerPathFeature = 
                context.Features.Get<IExceptionHandlerPathFeature>();

            // Use exceptionHandlerPathFeature to process the exception (for example, 
            // logging), but do NOT expose sensitive error information directly to 
            // the client.

            if (exceptionHandlerPathFeature?.Error is FileNotFoundException)
            {
                await context.Response.WriteAsync("File error thrown!<br><br>\r\n");
            }

            await context.Response.WriteAsync("<a href=\"/\">Home</a><br>\r\n");
            await context.Response.WriteAsync("</body></html>\r\n");
            await context.Response.WriteAsync(new string(' ', 512)); // IE padding
        });
    });
    app.UseHsts();
}

Avviso

Non fornire informazioni sugli errori sensibili da IExceptionHandlerFeature o IExceptionHandlerPathFeature ai client.Do not serve sensitive error information from IExceptionHandlerFeature or IExceptionHandlerPathFeature to clients. Fornire informazioni sugli errori rappresenta un rischio di sicurezza.Serving errors is a security risk.

Per visualizzare il risultato dell'espressione lambda di gestione delle eccezioni nell'app di esempio, usare le direttive del preprocessore ProdEnvironment e ErrorHandlerLambda e selezionare Trigger an exception (Attiva un'eccezione) nella home page.To see the result of the exception handling lambda in the sample app, use the ProdEnvironment and ErrorHandlerLambda preprocessor directives, and select Trigger an exception on the home page.

UseStatusCodePagesUseStatusCodePages

Per impostazione predefinita, un'app ASP.NET Core non offre una tabella codici di stato per i codici di stato HTTP, ad esempio 404 - Non trovato.By default, an ASP.NET Core app doesn't provide a status code page for HTTP status codes, such as 404 - Not Found. L'app restituisce un codice di stato e un corpo della risposta vuoto.The app returns a status code and an empty response body. Per specificare le tabelle codici di stato, usare il middleware delle tabelle codici di stato.To provide status code pages, use Status Code Pages middleware.

Il middleware è disponibile nel pacchetto Microsoft.AspNetCore.Diagnostics che si trova nel metapacchetto Microsoft.AspNetCore.App.The middleware is made available by the Microsoft.AspNetCore.Diagnostics package, which is in the Microsoft.AspNetCore.App metapackage.

Per abilitare i gestori di solo testo predefiniti per i codici di stato di errore comuni, chiamare UseStatusCodePages nel metodo Startup.Configure:To enable default text-only handlers for common error status codes, call UseStatusCodePages in the Startup.Configure method:

app.UseStatusCodePages();

Chiamare UseStatusCodePages prima del middleware di gestione delle richieste (ad esempio, middleware dei file statici e middleware MVC).Call UseStatusCodePages before request handling middleware (for example, Static File Middleware and MVC Middleware).

Di seguito è riportato un esempio del testo visualizzato dai gestori predefiniti:Here's an example of text displayed by the default handlers:

Status Code: 404; Not Found

Per visualizzare uno dei vari formati di tabella codici di stato nell'app di esempio, usare una delle direttive del preprocessore che iniziano con StatusCodePages e selezionare Trigger a 404 (Genera un 404) nella home page.To see one of the various status code page formats in the sample app, use one of the preprocessor directives that begin with StatusCodePages, and select Trigger a 404 on the home page.

UseStatusCodePages con stringa di formatoUseStatusCodePages with format string

Per personalizzare il tipo di contenuto della risposta e il testo, usare l'overload di UseStatusCodePages che accetta un tipo di contenuto e una stringa di formato:To customize the response content type and text, use the overload of UseStatusCodePages that takes a content type and format string:

app.UseStatusCodePages(
    "text/plain", "Status code page, status code: {0}");            

UseStatusCodePages con espressione lambdaUseStatusCodePages with lambda

Per specificare la gestione degli errori personalizzata e il codice per la scrittura delle risposte, usare l'overload di UseStatusCodePages che accetta un'espressione lambda:To specify custom error-handling and response-writing code, use the overload of UseStatusCodePages that takes a lambda expression:


app.UseStatusCodePages(async context =>
{
    context.HttpContext.Response.ContentType = "text/plain";

    await context.HttpContext.Response.WriteAsync(
        "Status code page, status code: " + 
        context.HttpContext.Response.StatusCode);
});

UseStatusCodePagesWithRedirectUseStatusCodePagesWithRedirect

Metodo di estensione UseStatusCodePagesWithRedirects:The UseStatusCodePagesWithRedirects extension method:

  • Invia un codice di stato 302 - Trovato al client.Sends a 302 - Found status code to the client.
  • Reindirizza il client al percorso specificato nel modello di URL.Redirects the client to the location provided in the URL template.
app.UseStatusCodePagesWithRedirects("/StatusCode?code={0}");

Il modello di URL può includere un segnaposto {0} per il codice di stato, come illustrato nell'esempio.The URL template can include a {0} placeholder for the status code, as shown in the example. Se il modello di URL inizia con una tilde (~), la tilde viene sostituita con il valore PathBase dell'app.If the URL template starts with a tilde (~), the tilde is replaced by the app's PathBase. Se si punta a un endpoint all'interno dell'app, creare una visualizzazione MVC o una pagina Razor per l'endpoint.If you point to an endpoint within the app, create an MVC view or Razor page for the endpoint. Per un esempio di Razor Pages, vedere StatusCode.cshtml nell'app di esempio.For a Razor Pages example, see Pages/StatusCode.cshtml in the sample app.

Questo metodo viene usato comunemente quando l'app:This method is commonly used when the app:

  • Deve reindirizzare il client a un endpoint diverso, in genere nei casi in cui un'altra app elabora l'errore.Should redirect the client to a different endpoint, usually in cases where a different app processes the error. Per le app Web, la barra degli indirizzi del browser del client riflette l'endpoint reindirizzato.For web apps, the client's browser address bar reflects the redirected endpoint.
  • Non deve conservare e restituire il codice di stato originale con la risposta di reindirizzamento iniziale.Shouldn't preserve and return the original status code with the initial redirect response.

UseStatusCodePagesWithReExecuteUseStatusCodePagesWithReExecute

Metodo di estensione UseStatusCodePagesWithReExecute:The UseStatusCodePagesWithReExecute extension method:

  • Restituisce il codice di stato originale al client.Returns the original status code to the client.
  • Genera il corpo della risposta eseguendo nuovamente la pipeline delle richieste con un percorso alternativo.Generates the response body by re-executing the request pipeline using an alternate path.
app.UseStatusCodePagesWithReExecute("/StatusCode","?code={0}");

Se si punta a un endpoint all'interno dell'app, creare una visualizzazione MVC o una pagina Razor per l'endpoint.If you point to an endpoint within the app, create an MVC view or Razor page for the endpoint. Per un esempio di Razor Pages, vedere StatusCode.cshtml nell'app di esempio.For a Razor Pages example, see Pages/StatusCode.cshtml in the sample app.

Questo metodo viene usato comunemente quando l'app deve:This method is commonly used when the app should:

  • Elaborare la richiesta senza il reindirizzamento a un endpoint diverso.Process the request without redirecting to a different endpoint. Per le app Web, la barra degli indirizzi del browser del client riflette l'endpoint richiesto in origine.For web apps, the client's browser address bar reflects the originally requested endpoint.
  • Conservare e restituire il codice di stato originale con la risposta.Preserve and return the original status code with the response.

I modelli di URL e di stringa di query potrebbero includere un segnaposto ({0}) per il codice di stato.The URL and query string templates may include a placeholder ({0}) for the status code. Il modello di URL deve iniziare con una barra (/).The URL template must start with a slash (/). Quando si usa un segnaposto nel percorso, verificare che l'endpoint (pagina o controller) possa elaborare il segmento del percorso.When using a placeholder in the path, confirm that the endpoint (page or controller) can process the path segment. Ad esempio, una pagina Razor per gli errori deve accettare il valore del segmento di percorso facoltativo con la direttiva @page:For example, a Razor Page for errors should accept the optional path segment value with the @page directive:

@page "{code?}"

L'endpoint che elabora l'errore può ottenere l'URL originale che ha generato l'errore, come illustrato nell'esempio seguente:The endpoint that processes the error can get the original URL that generated the error, as shown in the following example:

var statusCodeReExecuteFeature = HttpContext.Features.Get<IStatusCodeReExecuteFeature>();
if (statusCodeReExecuteFeature != null)
{
    OriginalURL =
        statusCodeReExecuteFeature.OriginalPathBase
        + statusCodeReExecuteFeature.OriginalPath
        + statusCodeReExecuteFeature.OriginalQueryString;
}

Disabilitare le tabelle codici di statoDisable status code pages

Per disabilitare le tabelle codici di stato per un controller MVC o un metodo di azione, usare l'attributo [SkipStatusCodePages].To disable status code pages for an MVC controller or action method, use the [SkipStatusCodePages] attribute.

Per disabilitare le tabelle codici di stato per richieste specifiche in un metodo del gestore Razor Pages o in un controller MVC, usare IStatusCodePagesFeature:To disable status code pages for specific requests in a Razor Pages handler method or in an MVC controller, use IStatusCodePagesFeature:

var statusCodePagesFeature = HttpContext.Features.Get<IStatusCodePagesFeature>();

if (statusCodePagesFeature != null)
{
    statusCodePagesFeature.Enabled = false;
}

Codice di gestione delle eccezioniException-handling code

Il codice in pagine di gestione delle eccezioni può generare eccezioni.Code in exception handling pages can throw exceptions. È spesso consigliabile che le pagine di errore di produzione contengano esclusivamente contenuto statico.It's often a good idea for production error pages to consist of purely static content.

Intestazioni della rispostaResponse headers

Dopo l'invio delle intestazioni per una risposta:Once the headers for a response are sent:

  • L'app non può modificare il codice di stato della risposta.The app can't change the response's status code.
  • Non è possibile eseguire pagine o gestori delle eccezioni.Any exception pages or handlers can't run. La risposta deve essere completata o la connessione deve essere interrotta.The response must be completed or the connection aborted.

Gestione delle eccezioni del serverServer exception handling

Oltre alla logica di gestione delle eccezioni nell'app, l'implementazione del server HTTP può gestire alcune eccezioni.In addition to the exception handling logic in your app, the HTTP server implementation can handle some exceptions. Se rileva un'eccezione prima dell'invio delle intestazioni di risposta, il server invia una risposta 500 - Errore interno del server senza corpo.If the server catches an exception before response headers are sent, the server sends a 500 - Internal Server Error response without a response body. Se il server rileva un'eccezione dopo l'invio delle intestazioni di risposta, il server chiude la connessione.If the server catches an exception after response headers are sent, the server closes the connection. Le richieste che non sono gestite dall'app vengono gestite dal server.Requests that aren't handled by your app are handled by the server. Qualsiasi eccezione che si verifica quando il server sta gestendo la richiesta viene gestita dalla gestione delle eccezioni del server.Any exception that occurs when the server is handling the request is handled by the server's exception handling. Eventuali pagine di errore personalizzate dell'app, middleware di gestione delle eccezioni e filtri non hanno effetto su questo comportamento.The app's custom error pages, exception handling middleware, and filters don't affect this behavior.

Gestione delle eccezioni durante l'avvioStartup exception handling

Solo il livello di hosting può gestire le eccezioni che si verificano durante l'avvio dell'app.Only the hosting layer can handle exceptions that take place during app startup. L'host può essere configurato per acquisire gli errori di avvio e acquisire errori dettagliati.The host can be configured to capture startup errors and capture detailed errors.

Il livello di hosting può visualizzare una pagina di errore per un errore di avvio acquisito solo se l'errore si verifica dopo l'associazione indirizzo host/porta.The hosting layer can show an error page for a captured startup error only if the error occurs after host address/port binding. Se si verifica un errore di associazione:If binding fails:

  • Il livello di hosting registra un'eccezione critica.The hosting layer logs a critical exception.
  • Si verifica un arresto anomalo del processo di dotnet.The dotnet process crashes.
  • Non viene visualizzata alcuna pagina di errore quando il server HTTP è Kestrel.No error page is displayed when the HTTP server is Kestrel.

Se durante l'esecuzione in IIS (o servizio app di Azure) o in IIS Express il processo non può essere avviato, viene restituito l'errore 502.5 Errore del processo dal modulo ASP.NET Core.When running on IIS (or Azure App Service) or IIS Express, a 502.5 - Process Failure is returned by the ASP.NET Core Module if the process can't start. Per altre informazioni, vedere Risolvere i problemi relativi a ASP.NET Core in app Azure servizio e IIS.For more information, see Risolvere i problemi relativi a ASP.NET Core in app Azure servizio e IIS.

Pagina di errore di databaseDatabase error page

Il middleware per la pagina degli errori del database acquisisce le eccezioni correlate al database che possono essere risolte con migrazioni di Entity Framework.The Database Error Page middleware captures database-related exceptions that can be resolved by using Entity Framework migrations. Quando si verificano queste eccezioni, viene generata una risposta HTML con i dettagli delle azioni possibili per risolvere il problema.When these exceptions occur, an HTML response with details of possible actions to resolve the issue is generated. Questa pagina deve essere abilitata solo nell'ambiente di sviluppo.This page should be enabled only in the Development environment. Abilitare la pagina aggiungendo codice Startup.Configure:Enable the page by adding code to Startup.Configure:

if (env.IsDevelopment())
{
    app.UseDatabaseErrorPage();
}

Filtri eccezioniException filters

Nelle app MVC i filtri delle eccezioni possono essere configurati a livello globale o per ogni controller o azione singolarmente.In MVC apps, exception filters can be configured globally or on a per-controller or per-action basis. Nelle app Razor Pages è possibile configurarli a livello globale o per ogni modello di pagina.In Razor Pages apps, they can be configured globally or per page model. Questi filtri gestiscono tutte le eccezioni non gestite che si verificano durante l'esecuzione di un'azione del controller o di un altro filtroThese filters handle any unhandled exception that occurs during the execution of a controller action or another filter. Per altre informazioni, vedere Filtri in ASP.NET Core.For more information, see Filtri in ASP.NET Core.

Suggerimento

I filtri delle eccezioni sono utili per intercettare le eccezioni che si verificano all'interno di azioni MVC, ma non sono flessibili come il middleware di gestione degli errori.Exception filters are useful for trapping exceptions that occur within MVC actions, but they're not as flexible as the Exception Handling Middleware. È consigliabile usare il middleware.We recommend using the middleware. Usare i filtri solo quando è necessario eseguire la gestione degli errori in modo diverso in base all'azione MVC scelta.Use filters only where you need to perform error handling differently based on which MVC action is chosen.

Errori di stato del modelloModel state errors

Per informazioni su come gestire gli errori dello stato del modello, vedere Associazione di modelli e Convalida del modello.For information about how to handle model state errors, see Model binding and Model validation.

Risorse aggiuntiveAdditional resources