Tratar erros no ASP.NET Core

Por Kirk Ltd, Tom Dykstrae Steve Smith

Este artigo aborda abordagens comuns para lidar com erros em ASP.NET Web Core. Consulte Tratar erros em APIs Web ASP.NET Core para APIs Web.

Exibir ou baixar o código de exemplo. (Como baixar.) A guia rede nas ferramentas de desenvolvedor do navegador F12 é útil ao testar o aplicativo de exemplo.

Página de exceção do desenvolvedor

A Página de Exceção do Desenvolvedor exibe informações detalhadas sobre exceções de solicitação sem tratativas. Os ASP.NET Core geram o seguinte código:

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }
    else
    {
        app.UseExceptionHandler("/Error");
        app.UseHsts();
    }

    app.UseHttpsRedirection();
    app.UseStaticFiles();

    app.UseRouting();

    app.UseAuthorization();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapRazorPages();
    });
}

O código realçado anterior habilita a página de exceção do desenvolvedor quando o aplicativo está em execução no ambiente de desenvolvimento.

Os modelos são lançados no início do pipeline de middleware para que ele possa capturar exceções sem UseDeveloperExceptionPage tratativas lançadas no middleware a seguir.

O código anterior habilita a Página de Exceção do Desenvolvedor somente quando o aplicativo é executado no ambiente de desenvolvimento. As informações de exceção detalhadas não devem ser exibidas publicamente quando o aplicativo é executado no ambiente de Produção. Para saber mais sobre a configuração de ambientes, confira Usar vários ambientes no ASP.NET Core.

A Página de Exceção do Desenvolvedor inclui as seguintes informações sobre a exceção e a solicitação:

  • Rastreamento de pilha
  • Parâmetros de cadeia de caracteres de consulta, se algum
  • Cookies, se algum
  • Cabeçalhos

Página do Manipulador de exceção

Para configurar uma página de tratamento de erro personalizada para o ambiente de Produção,chame UseExceptionHandler . Esse middleware de tratamento de exceção:

  • Captura e registra exceções sem-manuseio.
  • Executa a solicitação em um pipeline alternativo usando o caminho indicado. A solicitação não será executada novamente se a resposta tiver sido iniciada. O código gerado pelo modelo executa a solicitação usando o /Error caminho .

Aviso

Se o pipeline alternativo lançar uma exceção própria, o Middleware de Tratamento de Exceções lançará a exceção original.

No exemplo a seguir, adiciona o middleware de tratamento UseExceptionHandler de exceção em ambientes que não são de desenvolvimento:

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

O Razor modelo de aplicativo Pages fornece uma página erro ( ) e a classe ( ) na .cshtml PageModel ErrorModel pasta Pages. Para um aplicativo MVC, o modelo de projeto inclui um Error método de ação e uma exibição De erro para o Home controlador.

O middleware de tratamento de exceção executa a solicitação usando o método HTTP original. Se um ponto de extremidade do manipulador de erros estiver restrito a um conjunto específico de métodos HTTP, ele será executado somente para esses métodos HTTP. Por exemplo, uma ação do controlador MVC que usa o [HttpGet] atributo é executado somente para solicitações GET. Para garantir que todas as solicitações atinjam a página de tratamento de erro personalizada, não as restrinja a um conjunto específico de métodos HTTP.

Para lidar com exceções de forma diferente com base no método HTTP original:

  • Para Razor Páginas, crie vários métodos de manipulador. Por exemplo, use OnGet para lidar com exceções GET e use para lidar com exceções OnPost POST.
  • Para MVC, aplique atributos de verbo HTTP a várias ações. Por exemplo, use [HttpGet] para lidar com exceções GET e use para lidar com exceções [HttpPost] POST.

Para permitir que usuários não autenticados exibissem a página de tratamento de erro personalizada, verifique se ela dá suporte ao acesso anônimo.

Acessar a exceção

Use IExceptionHandlerPathFeature para acessar a exceção e o caminho de solicitação original em um manipulador de erros. O código a seguir ExceptionMessage adiciona a Pages/Error.cshtml.cs padrão geradas pelos modelos ASP.NET Core:

[ResponseCache(Duration=0, Location=ResponseCacheLocation.None, NoStore=true)]
[IgnoreAntiforgeryToken]
public class ErrorModel : PageModel
{
    public string RequestId { get; set; }
    public bool ShowRequestId => !string.IsNullOrEmpty(RequestId);
    public string ExceptionMessage { get; set; }
    private readonly ILogger<ErrorModel> _logger;

    public ErrorModel(ILogger<ErrorModel> logger)
    {
        _logger = logger;
    }

    public void OnGet()
    {
        RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier;

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

Aviso

Não forneça informações de erro confidenciais aos clientes. Fornecer erros é um risco à segurança.

Para testar a exceção no aplicativo de exemplo:

  • Definir o ambiente como produção.
  • Remova os comentários de webBuilder.UseStartup<Startup>(); em Program.cs .
  • Selecione Disparar uma exceção no home page.

Lambda do Manipulador de exceção

Uma alternativa a uma página personalizada de manipulador de exceção é fornecer um lambda a UseExceptionHandler. Usar um lambda permite acessar o erro antes de retornar a resposta.

O código a seguir usa um lambda para tratamento de exceção:

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }
    else
    {
        app.UseExceptionHandler(errorApp =>
        {
            errorApp.Run(async context =>
            {
                context.Response.StatusCode = (int) HttpStatusCode.InternalServerError;;
                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>();

                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)); 
            });
        });
        app.UseHsts();
    }

    app.UseHttpsRedirection();
    app.UseStaticFiles();

    app.UseRouting();

    app.UseAuthorization();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapRazorPages();
    });
}

Aviso

Não forneça informações de erro confidenciais de IExceptionHandlerFeature ou IExceptionHandlerPathFeature para clientes. Fornecer erros é um risco à segurança.

Para testar o tratamento de exceção lambda no aplicativo de exemplo:

  • Definir o ambiente como produção.
  • Remova os comentários de webBuilder.UseStartup<StartupLambda>(); em Program.cs .
  • Selecione Disparar uma exceção no home page.

UseStatusCodePages

Por padrão, um ASP.NET Core não fornece uma página de código de status para códigos de status de erro HTTP, como 404 – Não Encontrado. Quando o aplicativo encontra um código de status de erro HTTP 400-599 que não tem um corpo, ele retorna o código de status e um corpo de resposta vazio. Para fornecer páginas de código de status, use o middleware de páginas de código de status. Para habilitar os manipuladores padrão somente texto para os códigos de status de erros comuns, chame UseStatusCodePages no método Startup.Configure:

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }
    else
    {
        app.UseExceptionHandler("/Error");
        app.UseHsts();
    }

    app.UseStatusCodePages();

    app.UseHttpsRedirection();
    app.UseStaticFiles();

    app.UseRouting();

    app.UseAuthorization();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapRazorPages();
    });
}

Chame antes UseStatusCodePages do middleware de tratamento de solicitação. Por exemplo, chame UseStatusCodePages antes do Middleware de Arquivos Estáticos e do Middleware de Pontos de Extremidade.

Quando não é usado, navegar até uma URL sem um ponto de extremidade retorna uma mensagem de erro dependente do navegador indicando que o ponto de extremidade UseStatusCodePages não pode ser encontrado. Por exemplo, navegando até Home/Privacy2 . Quando UseStatusCodePages é chamado, o navegador retorna:

Status Code: 404; Not Found

UseStatusCodePages normalmente não é usado em produção porque retorna uma mensagem que não é útil para os usuários.

Para testar UseStatusCodePages no aplicativo de exemplo:

  • Definir o ambiente como produção.
  • Remova os comentários de webBuilder.UseStartup<StartupUseStatusCodePages>(); em Program.cs .
  • Selecione os links na home page no home page.

Observação

O middleware de páginas de código de status não captura exceções. Para fornecer uma página de tratamento de erro personalizada, use a página do manipulador de exceção.

UseStatusCodePages com cadeia de caracteres de formato

Para personalizar o texto e o tipo de conteúdo de resposta, use uma sobrecarga de UseStatusCodePages que leva um tipo de conteúdo e uma cadeia de caracteres de formato:

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }
    else
    {
        app.UseExceptionHandler("/Error");
        app.UseHsts();
    }

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

    app.UseHttpsRedirection();
    app.UseStaticFiles();

    app.UseRouting();

    app.UseAuthorization();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapRazorPages();
    });
}

No código anterior, é {0} um espaço reservado para o código de erro.

UseStatusCodePages com uma cadeia de caracteres de formato normalmente não é usada em produção porque retorna uma mensagem que não é útil para os usuários.

Para testar UseStatusCodePages no aplicativo de exemplo, remova os comentários de webBuilder.UseStartup<StartupFormat>(); no Program.cs .

UseStatusCodePages com lambda

Para especificar a manipulação de erro personalizada e o código de gravação de resposta, use a sobrecarga de UseStatusCodePages que leva uma expressão lambda:

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }
    else
    {
        app.UseExceptionHandler("/Error");
        app.UseHsts();
    }

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

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

    app.UseHttpsRedirection();
    app.UseStaticFiles();

    app.UseRouting();

    app.UseAuthorization();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapRazorPages();
    });
}

UseStatusCodePages com um lambda normalmente não é usado em produção porque ele retorna uma mensagem que não é útil para os usuários.

Para testar UseStatusCodePages no aplicativo de exemplo, remova os comentários de webBuilder.UseStartup<StartupStatusLambda>(); no Program.cs .

UseStatusCodePagesWithRedirects

O método de extensão UseStatusCodePagesWithRedirects:

  • Envia um código de status 302 – Encontrado ao cliente.
  • Redireciona o cliente para o ponto de extremidade de tratamento de erro fornecido no modelo de URL. O ponto de extremidade de tratamento de erro normalmente exibe informações de erro e retorna HTTP 200.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }
    else
    {
        app.UseExceptionHandler("/Error");
        app.UseHsts();
    }

    app.UseStatusCodePagesWithRedirects("/MyStatusCode?code={0}");

    app.UseHttpsRedirection();
    app.UseStaticFiles();

    app.UseRouting();

    app.UseAuthorization();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapRazorPages();
    });
}

O modelo de URL pode incluir {0} um espaço reservado para o código de status, conforme mostrado no código anterior. Se o modelo de URL começar com ~ (til), ~ o será substituído pelo do PathBase aplicativo. Ao especificar um ponto de extremidade no aplicativo, crie uma exibição ou página do MVC Razor para o ponto de extremidade. Para ver Razor um exemplo de Páginas, consulte Pages/MyStatusCode.cshtml no aplicativo de exemplo.

Este método normalmente é usado quando o aplicativo:

  • Deveria redirecionar o cliente para um terminal diferente, geralmente em situações nas quais um aplicativo diferente processa o erro. Para aplicativos Web, a barra de endereços do navegador do cliente reflete o ponto de extremidade redirecionado.
  • Não deveria preservar e retornar o código de status original com a resposta de redirecionamento inicial.

Para testar UseStatusCodePages no aplicativo de exemplo, remova os comentários de webBuilder.UseStartup<StartupSCredirect>(); no Program.cs .

UseStatusCodePagesWithReExecute

O método de extensão UseStatusCodePagesWithReExecute:

  • Retorna o código de status original ao cliente.
  • Gera o corpo da resposta ao executar novamente o pipeline de solicitação por meio de um caminho alternativo.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }
    else
    {
        app.UseExceptionHandler("/Error");
        app.UseHsts();
    }

    app.UseStatusCodePagesWithReExecute("/MyStatusCode2", "?code={0}");

    app.UseHttpsRedirection();
    app.UseStaticFiles();

    app.UseRouting();

    app.UseAuthorization();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapRazorPages();
    });
}

Se um ponto de extremidade dentro do aplicativo for especificado, crie uma exibição ou página do MVC Razor para o ponto de extremidade. Verifique UseStatusCodePagesWithReExecute se foi colocado antes para que a UseRouting solicitação possa ser redirecionada para a página de status. Para ver Razor um exemplo de Páginas, consulte Pages/MyStatusCode2.cshtml no aplicativo de exemplo.

Este método normalmente é usado quando o aplicativo tem que:

  • Processar a solicitação sem redirecionar para um ponto de extremidade diferente. Para aplicativos Web, a barra de endereços do navegador do cliente reflete o ponto de extremidade originalmente solicitado.
  • Preservar e retornar o código de status original com a resposta.

A URL e os modelos de cadeia de caracteres de consulta podem incluir um espaço reservado {0} para o código de status. O modelo de URL deve começar com / .

O ponto de extremidade que processa o erro pode obter a URL original que gerou o erro, conforme mostrado no exemplo a seguir:

[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
public class MyStatusCode2Model : PageModel
{
    public string RequestId { get; set; }
    public bool ShowRequestId => !string.IsNullOrEmpty(RequestId);

    public string ErrorStatusCode { get; set; }

    public string OriginalURL { get; set; }
    public bool ShowOriginalURL => !string.IsNullOrEmpty(OriginalURL);

    public void OnGet(string code)
    {
        RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier;
        ErrorStatusCode = code;

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

Para ver Razor um exemplo de Páginas, consulte Pages/MyStatusCode2.cshtml no aplicativo de exemplo.

Para testar UseStatusCodePages no aplicativo de exemplo, remova os comentários de webBuilder.UseStartup<StartupSCreX>(); no Program.cs .

Desabilitar páginas de código de status

Para desabilitar as páginas de código de status de um método de ação ou controlador MVC, use o atributo [SkipStatusCodePages].

Para desabilitar páginas de código de status para solicitações específicas em um método de manipulador pages Razor ou em um controlador MVC, use IStatusCodePagesFeature :

public void OnGet()
{
    // using Microsoft.AspNetCore.Diagnostics;
    var statusCodePagesFeature = HttpContext.Features.Get<IStatusCodePagesFeature>();

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

Código de tratamento de exceção

O código em páginas de tratamento de exceção também pode lançar exceções. As páginas de erro de produção devem ser totalmente testadas e tomar cuidado extra para evitar lançar exceções próprias.

Cabeçalhos de resposta

Depois que os cabeçalhos de resposta são enviados:

  • O aplicativo já não consegue alterar o código de status da resposta.
  • As páginas de exceção ou manipuladores não podem ser executados. A resposta deve ser concluída ou a conexão será anulada.

Tratamento de exceções do servidor

Além da lógica de tratamento de exceção em um aplicativo, a implementação do servidor HTTP pode lidar com algumas exceções. Se o servidor capturar uma exceção antes que os headers de resposta sejam enviados, o servidor enviará 500 - Internal Server Error uma resposta sem um corpo de resposta. Se o servidor capturar uma exceção depois que os cabeçalhos de resposta forem enviados, o servidor fechará a conexão. As solicitações que não são manipuladas pelo aplicativo são manipuladas pelo servidor. Qualquer exceção que ocorrer quando o servidor estiver tratando a solicitação será tratada pelo tratamento de exceção do servidor. As páginas de erro personalizadas do aplicativo, o middleware de tratamento de exceção e os filtros configurados não afetam esse comportamento.

Tratamento de exceção na inicialização

Apenas a camada de hospedagem pode tratar exceções que ocorrem durante a inicialização do aplicativo. O host pode ser configurado para capturar erros de inicialização e capturar erros detalhados.

A camada de hospedagem só poderá mostrar uma página de erro para um erro de inicialização capturado se o erro ocorrer após a associação de endereço do host/porta. Se a associação falhar:

  • A camada de hospedagem registrará uma exceção crítica.
  • O processo dotnet falhará.
  • Nenhuma página de erro é exibida quando o servidor HTTP é Kestrel .

Quando executado no IIS (ou no Serviço de Aplicativo do Azure) ou no IIS Express, um erro 502.5 Falha no Processo será retornado pelo Módulo do ASP.NET Core se o processo não puder ser iniciado. Para obter mais informações, consulte Solucionar problemas ASP.NET Core no serviço Azure App e no IIS.

Página de erro do banco de dados

O filtro de exceção da página do desenvolvedor de banco de dados captura exceções relacionadas ao banco de dados que podem AddDatabaseDeveloperPageExceptionFilter ser resolvidas usando Entity Framework Core migrações. Quando essas exceções ocorrem, uma resposta HTML é gerada com detalhes de possíveis ações para resolver o problema. Esta página está habilitada somente no ambiente de desenvolvimento. O código a seguir foi gerado pelos modelos ASP.NET Páginas Razor Principais quando contas de usuário individuais foram especificadas:

public void ConfigureServices(IServiceCollection services)
{
    services.AddDbContext<ApplicationDbContext>(options =>
        options.UseSqlServer(
            Configuration.GetConnectionString("DefaultConnection")));
    services.AddDatabaseDeveloperPageExceptionFilter();
    services.AddDefaultIdentity<IdentityUser>(options => options.SignIn.RequireConfirmedAccount = true)
        .AddEntityFrameworkStores<ApplicationDbContext>();
    services.AddRazorPages();
}

Filtros de exceção

Em aplicativos MVC, os filtros de exceção podem ser configurados globalmente, por controlador ou por ação. Em Razor aplicativos pages, eles podem ser configurados globalmente ou por modelo de página. Esses filtros lidam com exceções sem tratamento que ocorrem durante a execução de uma ação do controlador ou outro filtro. Para obter mais informações, consulte Filtros no ASP.NET Core.

Os filtros de exceção são úteis para interceptar exceções que ocorrem em ações do MVC, mas não são tão flexíveis quanto o middleware de tratamento de exceções integrado, UseExceptionHandler . É recomendável usar , a menos que você precise executar o tratamento de erro de forma UseExceptionHandler diferente com base em qual ação do MVC é escolhida.

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }
    else
    {
        app.UseExceptionHandler("/Error");
        app.UseHsts();
    }

    app.UseHttpsRedirection();
    app.UseStaticFiles();

    app.UseRouting();

    app.UseAuthorization();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapRazorPages();
    });
}

Erros de estado do modelo

Confira informações sobre como lidar com erros de estado de modelo em model binding e Validação de modelos.

Recursos adicionais

Por Tom Dykstrae Steve Smith

Este artigo aborda abordagens comuns para lidar com erros em ASP.NET Web Core. Consulte Tratar erros em APIs Web ASP.NET Core para APIs Web.

Exibir ou baixar o código de exemplo. (Como baixar.)

Página de exceção do desenvolvedor

A Página de exceção do desenvolvedor exibe informações detalhadas sobre as exceções de solicitação. Os ASP.NET Core geram o seguinte código:

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

O código anterior habilita a página de exceção do desenvolvedor quando o aplicativo está em execução no ambiente de desenvolvimento.

Os modelos são colocado antes de qualquer middleware para que as exceções sejam UseDeveloperExceptionPage capturadas no middleware a seguir.

O código anterior habilita a Página de Exceção do Desenvolvedor somente quando o aplicativo está em execução no ambiente de desenvolvimento. Informações de exceção detalhadas não devem ser exibidas publicamente quando o aplicativo é executado em produção. Para saber mais sobre a configuração de ambientes, confira Usar vários ambientes no ASP.NET Core.

A Página de Exceção do Desenvolvedor inclui as seguintes informações sobre a exceção e a solicitação:

  • Rastreamento de pilha
  • Parâmetros de cadeia de caracteres de consulta, se algum
  • Cookies, se algum
  • Cabeçalhos

Página do Manipulador de exceção

Use o Middleware de tratamento de exceção para configurar uma página personalizada de tratamento de erro para o ambiente de produção. O middleware:

  • Captura e registra em log as exceções.
  • Executa novamente a solicitação em um pipeline alternativo para a página ou controlador indicado. A solicitação não será executada novamente se a resposta tiver sido iniciada. O código gerado pelo modelo executa a solicitação para /Error .

No exemplo a seguir, UseExceptionHandler inclui o Middleware de Manipulação de Exceções em ambientes que não são de desenvolvimento:

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

O Razor modelo de aplicativo Pages fornece uma página erro ( ) e a classe ( ) na .cshtml PageModel ErrorModel pasta Pages. Para um aplicativo MVC, o modelo de projeto inclui um método de ação Error e uma exibição De erro no Home controlador.

Não marque o método de ação do manipulador de erros com atributos de método HTTP, como HttpGet . Verbos explícitos impedem algumas solicitações de chegar ao método. Permitir acesso anônimo ao método se usuários não autenticados devem ver a exibição de erro.

Acessar a exceção

Use IExceptionHandlerPathFeature para acessar a exceção e o caminho de solicitação original em uma página ou controlador de manipulador de erro:

[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
public class ErrorModel : PageModel
{
    public string RequestId { get; set; }
    public bool ShowRequestId => !string.IsNullOrEmpty(RequestId);
    public string ExceptionMessage { get; set; }

    public void OnGet()
    {
        RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier;

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

Aviso

Não forneça informações de erro confidenciais aos clientes. Fornecer erros é um risco à segurança.

Para disparar a página de tratamento de exceção anterior, de definir o ambiente como produção e forçar uma exceção.

Lambda do Manipulador de exceção

Uma alternativa a uma página personalizada de manipulador de exceção é fornecer um lambda a UseExceptionHandler. Usar um lambda permite acessar o erro antes de retornar a resposta.

Este é um exemplo de como usar um lambda para a manipulação de exceção:

if (env.IsDevelopment())
{
    app.UseDeveloperExceptionPage();
}
else
{
   app.UseExceptionHandler(errorApp =>
   {
        errorApp.Run(async context =>
        {
            context.Response.StatusCode = (int) HttpStatusCode.InternalServerError;
            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>();

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

No código anterior, await context.Response.WriteAsync(new string(' ', 512)); é adicionado para que o navegador Internet Explorer exiba a mensagem de erro em vez de uma mensagem de erro do IE. Saiba mais neste tópico do GitHub.

Aviso

Não forneça informações de erro confidenciais de IExceptionHandlerFeature ou IExceptionHandlerPathFeature para clientes. Fornecer erros é um risco à segurança.

Para ver o resultado do lambda de tratamento de exceções no aplicativo de exemplo, use as diretivas de pré-processador ProdEnvironment e ErrorHandlerLambda e selecione Disparar uma exceção na página inicial.

UseStatusCodePages

Por padrão, o aplicativo ASP.NET Core não fornece uma página de código de status para códigos de status HTTP, como 404 - Não Encontrado. O aplicativo retornar um código de status e um corpo de resposta vazio. Use o middleware das Páginas de código de status para fornecer páginas de código de status.

O middleware é disponibilizado pelo pacote Microsoft. AspNetCore. Diagnostics .

Para habilitar os manipuladores padrão somente texto para os códigos de status de erros comuns, chame UseStatusCodePages no método Startup.Configure:

app.UseStatusCodePages();

Chame UseStatusCodePages antes do middleware de tratamento da solicitação (por exemplo, o middleware de arquivos estáticos e o middleware MVC).

Quando UseStatusCodePages não é usado, navegar para uma URL sem um ponto de extremidade retorna uma mensagem de erro dependente do navegador indicando que o ponto de extremidade não foi encontrado. Por exemplo, navegando até Home/Privacy2 . Quando UseStatusCodePages é chamado, o navegador retorna:

Status Code: 404; Not Found

UseStatusCodePages com cadeia de caracteres de formato

Para personalizar o texto e o tipo de conteúdo de resposta, use uma sobrecarga de UseStatusCodePages que leva um tipo de conteúdo e uma cadeia de caracteres de formato:

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

UseStatusCodePages com lambda

Para especificar a manipulação de erro personalizada e o código de gravação de resposta, use a sobrecarga de UseStatusCodePages que leva uma expressão lambda:


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

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

UseStatusCodePagesWithRedirects

O método de extensão UseStatusCodePagesWithRedirects:

  • Envia um código de status 302 – Encontrado ao cliente.
  • Redireciona o cliente para o local fornecido no modelo de URL.
app.UseStatusCodePagesWithRedirects("/StatusCode?code={0}");

O modelo de URL pode incluir um espaço reservado {0} para o código de status, conforme mostrado no exemplo. Se o modelo de URL começar com ~ (til), o ~ será substituído pelo aplicativo PathBase . Se você apontar para um ponto de extremidade dentro do aplicativo, crie uma exibição ou Razor página do MVC para o ponto de extremidade. Para obter um Razor exemplo de páginas, consulte páginas/StatusCode. cshtml no aplicativo de exemplo.

Este método normalmente é usado quando o aplicativo:

  • Deveria redirecionar o cliente para um terminal diferente, geralmente em situações nas quais um aplicativo diferente processa o erro. Para aplicativos Web, a barra de endereços do navegador do cliente reflete o ponto de extremidade redirecionado.
  • Não deveria preservar e retornar o código de status original com a resposta de redirecionamento inicial.

UseStatusCodePagesWithReExecute

O método de extensão UseStatusCodePagesWithReExecute:

  • Retorna o código de status original ao cliente.
  • Gera o corpo da resposta ao executar novamente o pipeline de solicitação por meio de um caminho alternativo.
app.UseStatusCodePagesWithReExecute("/StatusCode","?code={0}");

Se você apontar para um ponto de extremidade dentro do aplicativo, crie uma exibição ou Razor página do MVC para o ponto de extremidade. Certifique-se UseStatusCodePagesWithReExecute de que é colocado antes UseRouting para que a solicitação possa ser redirecionada para a página de status. Para obter um Razor exemplo de páginas, consulte páginas/StatusCode. cshtml no aplicativo de exemplo.

Este método normalmente é usado quando o aplicativo tem que:

  • Processar a solicitação sem redirecionar para um ponto de extremidade diferente. Para aplicativos Web, a barra de endereços do navegador do cliente reflete o ponto de extremidade originalmente solicitado.
  • Preservar e retornar o código de status original com a resposta.

Os modelos de URL e cadeia de caracteres de consulta podem incluir um espaço reservado ({0}) para o código de status. O modelo de URL deve começar com uma barra (/). Ao usar um espaço reservado no caminho, verifique se o ponto de extremidade (página ou controlador) pode processar o segmento de linha. Por exemplo, uma Razor página de erros deve aceitar o valor do segmento de caminho opcional com a @page diretiva:

@page "{code?}"

O ponto de extremidade que processa o erro pode obter a URL original que gerou o erro, conforme mostrado no exemplo a seguir:

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

Não marque o método de ação do manipulador de erros com atributos do método HTTP, como HttpGet . Verbos explícitos impedem algumas solicitações de chegar ao método. Permitir acesso anônimo ao método se usuários não autenticados devem ver o modo de exibição de erro.

Desabilitar páginas de código de status

Para desabilitar páginas de código de status para um controlador MVC ou um método de ação, use o [SkipStatusCodePages] atributo.

Para desabilitar as páginas de código de status para solicitações específicas em um Razor método de manipulador de páginas ou em um controlador MVC, use IStatusCodePagesFeature :

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

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

Código de tratamento de exceção

Código em páginas de tratamento de exceção pode gerar exceções. Geralmente, é uma boa ideia que páginas de erro de produção sejam compostas por conteúdo puramente estático.

Cabeçalhos de resposta

Depois que os cabeçalhos de resposta são enviados:

  • O aplicativo já não consegue alterar o código de status da resposta.
  • As páginas de exceção ou manipuladores não podem ser executados. A resposta deve ser concluída ou a conexão será anulada.

Tratamento de exceções do servidor

Além da lógica de tratamento de exceção no aplicativo, a implementação do servidor HTTP pode lidar com algumas exceções. Se o servidor capturar uma exceção antes que os cabeçalhos de resposta sejam enviados, o servidor enviará uma resposta 500 Erro Interno do Servidor sem um corpo de resposta. Se o servidor capturar uma exceção depois que os cabeçalhos de resposta forem enviados, o servidor fechará a conexão. As solicitações que não são manipuladas pelo aplicativo são manipuladas pelo servidor. Qualquer exceção que ocorrer quando o servidor estiver tratando a solicitação será tratada pelo tratamento de exceção do servidor. As páginas de erro personalizadas do aplicativo, o middleware de tratamento de exceção e os filtros configurados não afetam esse comportamento.

Tratamento de exceção na inicialização

Apenas a camada de hospedagem pode tratar exceções que ocorrem durante a inicialização do aplicativo. O host pode ser configurado para capturar erros de inicialização e capturar erros detalhados.

A camada de hospedagem só poderá mostrar uma página de erro para um erro de inicialização capturado se o erro ocorrer após a associação de endereço do host/porta. Se a associação falhar:

  • A camada de hospedagem registrará uma exceção crítica.
  • O processo dotnet falhará.
  • Nenhuma página de erro é exibida quando o servidor HTTP é Kestrel .

Quando executado no IIS (ou no Serviço de Aplicativo do Azure) ou no IIS Express, um erro 502.5 Falha no Processo será retornado pelo Módulo do ASP.NET Core se o processo não puder ser iniciado. Para obter mais informações, consulte Solucionar problemas ASP.NET Core no serviço Azure App e no IIS.

Página de erro do banco de dados

O middleware da página de erro do banco de dados captura as exceções relacionadas ao banco de dados que podem ser resolvidas usando Entity Framework migrações. Quando estas exceções ocorrem, é gerada uma resposta HTML com detalhes das ações possíveis para resolver o problema. Esta página só deve ser habilitada no Ambiente de desenvolvimento. Habilite a página adicionando código a Startup.Configure:

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

UseDatabaseErrorPage requer o pacote NuGet Microsoft. AspNetCore. Diagnostics. EntityFrameworkCore .

Filtros de exceção

Em aplicativos MVC, os filtros de exceção podem ser configurados globalmente, por controlador ou por ação. Em Razor páginas aplicativos, eles podem ser configurados globalmente ou por modelo de página. Esses filtros tratam qualquer exceção sem tratamento ocorrida durante a execução de uma ação do controlador ou de outro filtro. Para obter mais informações, consulte Filtros no ASP.NET Core.

Dica

Os filtros de exceção são úteis para interceptar exceções que ocorrem em ações do MVC, mas não são tão flexíveis quanto o middleware de tratamento de exceção. É recomendável usar o middleware. Use filtros somente onde você precisar fazer o tratamento de erro de forma diferente com base na ação de MVC escolhida.

Erros de estado do modelo

Confira informações sobre como lidar com erros de estado de modelo em model binding e Validação de modelos.

Recursos adicionais