Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
Observação
Esta não é a versão mais recente deste artigo. Para ver a versão atual, consulte a versão .NET 10 deste artigo.
Aviso
Esta versão do ASP.NET Core não tem mais suporte. Para obter mais informações, consulte o .NET e .NET Core Support Policy. Para ver a versão atual, consulte a versão .NET 10 deste artigo.
Este artigo descreve como lidar com erros em APIs de ASP.NET Core. A documentação para APIs Mínimas está selecionada. Para ver a documentação das APIs baseadas em controlador, selecione a guia Controllers. Para diretrizes de tratamento de erros, consulte Blazor.
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 não tratadas. Ele usa DeveloperExceptionPageMiddleware para capturar exceções síncronas e assíncronas do pipeline HTTP e para gerar respostas de erro. A página de exceção de desenvolvedor é executada no início do pipeline do middleware, para que ela possa capturar exceções sem tratamento lançadas no middleware subsequente.
Os aplicativos ASP.NET Core habilitam a página de exceção do desenvolvedor por padrão quando ambos estão presentes:
- Em execução no ambiente
Development. - O aplicativo foi criado com os modelos atuais, ou seja, usando WebApplication.CreateBuilder.
Os aplicativos criados usando modelos anteriores, ou seja, usando WebHost.CreateDefaultBuilder, podem ativar a página de exceção do desenvolvedor chamando app.UseDeveloperExceptionPage.
Aviso
Não habilite a Página de Exceção do Desenvolvedor, a menos que o aplicativo esteja em execução no Development ambiente. Não compartilhe informações detalhadas de exceção publicamente quando o aplicativo for executado em produção. Para obter mais informações sobre como configurar ambientes, consulte ASP.NET Core ambientes de runtime.
A Página de Exceção do Desenvolvedor pode incluir as seguintes informações sobre a exceção e a solicitação:
- Rastreamento de pilha
- Parâmetros de cadeia de caracteres de consulta, se houver
- Cookies, se houver
- Headers
- Metadados de ponto de extremidade, se houver
A Página de Exceção do Desenvolvedor não tem garantia de fornecer nenhuma informação. Use Registro em log para obter informações de erro completas.
A imagem a seguir mostra um exemplo de página de exceção de desenvolvedor, com animação para mostrar as guias e as informações exibidas.
Em resposta a uma solicitação com um cabeçalho Accept: text/plain, a Página de Exceção do Desenvolvedor retorna texto sem formatação em vez de HTML. Por exemplo:
Status: 500 Internal Server Error
Time: 9.39 msSize: 480 bytes
FormattedRawHeadersRequest
Body
text/plain; charset=utf-8, 480 bytes
System.InvalidOperationException: Sample Exception
at WebApplicationMinimal.Program.<>c.<Main>b__0_0() in C:\Source\WebApplicationMinimal\Program.cs:line 12
at lambda_method1(Closure, Object, HttpContext)
at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddlewareImpl.Invoke(HttpContext context)
HEADERS
=======
Accept: text/plain
Host: localhost:7267
traceparent: 00-0eab195ea19d07b90a46cd7d6bf2f
Para ver a página de exceção do desenvolvedor em uma API mínima:
- Execute o aplicativo de exemplo no
Developmentambiente. - Acesse o endpoint
/exception.
Esta seção refere-se ao aplicativo de exemplo a seguir para demonstrar maneiras de lidar com exceções em uma API Mínima. Ele lança uma exceção quando o endpoint /exception é solicitado:
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
app.MapGet("/exception", () =>
{
throw new InvalidOperationException("Sample Exception");
});
app.MapGet("/", () => "Test by calling /exception");
app.Run();
Manipulador de exceção
Em ambientes que não são de desenvolvimento, use o middleware de tratamento de exceções para gerar uma carga de erro.
Para configurar a exception handler middleware, chame UseExceptionHandler. Por exemplo, o código a seguir altera o aplicativo para responder com uma carga compatível com RFC 7807 para o cliente. Para obter mais informações, consulte a seção Detalhes do Problema mais adiante neste artigo.
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
app.UseExceptionHandler(exceptionHandlerApp
=> exceptionHandlerApp.Run(async context
=> await Results.Problem()
.ExecuteAsync(context)));
app.MapGet("/exception", () =>
{
throw new InvalidOperationException("Sample Exception");
});
app.MapGet("/", () => "Test by calling /exception");
app.Run();
Respostas de erro de cliente e servidor
Considere o aplicativo de API Mínimo a seguir.
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
app.MapGet("/users/{id:int}", (int id)
=> id <= 0 ? Results.BadRequest() : Results.Ok(new User(id)));
app.MapGet("/", () => "Test by calling /users/{id:int}");
app.Run();
public record User(int Id);
O /users endpoint produz 200 OK com uma representação json de User quando id é maior que 0; caso contrário, 400 BAD REQUEST código de status sem corpo de resposta. Para obter mais informações sobre como criar uma resposta, consulte Criar respostas em aplicativos de API mínimos.
O Status Code Pages middleware pode ser configurado para produzir um conteúdo comum para o corpo, quando vazio, para todas as respostas de cliente HTTP (400-499) ou de servidor (500 -599). O middleware é configurado chamando o método de extensão UseStatusCodePages .
Por exemplo, o exemplo a seguir altera o aplicativo para responder ao cliente com uma carga útil compatível com RFC 7807 para todas as respostas de cliente e de servidor, incluindo erros de roteamento (por exemplo, 404 NOT FOUND). Para obter mais informações, consulte a seção Detalhes do Problema .
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
app.UseStatusCodePages(async statusCodeContext
=> await Results.Problem(statusCode: statusCodeContext.HttpContext.Response.StatusCode)
.ExecuteAsync(statusCodeContext.HttpContext));
app.MapGet("/users/{id:int}", (int id)
=> id <= 0 ? Results.BadRequest() : Results.Ok(new User(id)) );
app.MapGet("/", () => "Test by calling /users/{id:int}");
app.Run();
public record User(int Id);
Detalhes do problema
Os Detalhes do problema não são o único formato de resposta a descrever um erro de API HTTP; no entanto, eles geralmente são usados para relatar erros para APIs HTTP.
O serviço de detalhes do problema implementa a interface IProblemDetailsService, que dá suporte à criação de detalhes do problema no ASP.NET Core. O método de extensão AddProblemDetails(IServiceCollection) em IServiceCollection regista a implementação IProblemDetailsService padrão.
Em aplicativos ASP.NET Core, o middleware a seguir gera respostas HTTP de detalhes do problema quando AddProblemDetails é chamado, exceto quando o cabeçalho HTTP da solicitação Accept não inclui um dos tipos de conteúdo compatíveis com o IProblemDetailsWriter registrado (padrão: application/json):
- ExceptionHandlerMiddleware: gera uma resposta de detalhes do problema quando um manipulador personalizado não é definido.
- StatusCodePagesMiddleware: gera uma resposta de detalhes do problema por padrão.
-
DeveloperExceptionPageMiddleware: Gera uma resposta de detalhes do problema no desenvolvimento quando o cabeçalho HTTP da solicitação
Acceptnão incluitext/html.
Aplicativos de API mínima podem ser configurados para gerar respostas com detalhes do problema para todas as respostas de erro HTTP do cliente e do servidor que ainda não têm corpo, usando o método de extensão AddProblemDetails.
O código a seguir configura o aplicativo para gerar detalhes do problema:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddProblemDetails();
var app = builder.Build();
app.UseExceptionHandler();
app.UseStatusCodePages();
app.MapGet("/users/{id:int}", (int id)
=> id <= 0 ? Results.BadRequest() : Results.Ok(new User(id)));
app.MapGet("/", () => "Test by calling /users/{id:int}");
app.Run();
public record User(int Id);
Para obter mais informações sobre como usar AddProblemDetails, consulte Detalhes do problema
Fallback IProblemDetailsService
No código a seguir, httpContext.Response.WriteAsync("Fallback: An error occurred.") retornará um erro se a IProblemDetailsService implementação não for capaz de gerar um ProblemDetails:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddProblemDetails();
var app = builder.Build();
app.UseExceptionHandler(exceptionHandlerApp =>
{
exceptionHandlerApp.Run(async httpContext =>
{
var pds = httpContext.RequestServices.GetService<IProblemDetailsService>();
if (pds == null
|| !await pds.TryWriteAsync(new() { HttpContext = httpContext }))
{
// Fallback behavior
await httpContext.Response.WriteAsync("Fallback: An error occurred.");
}
});
});
app.MapGet("/exception", () =>
{
throw new InvalidOperationException("Sample Exception");
});
app.MapGet("/", () => "Test by calling /exception");
app.Run();
O código anterior:
- Grava uma mensagem de erro com o código de fallback se o
problemDetailsServicenão conseguir gravar umProblemDetails. Por exemplo, um ponto de extremidade em que o cabeçalho de solicitação Accept especifica um tipo de mídia ao qual oDefaultProblemDetailsWriternão oferece suporte. - Usa o middleware de tratamento de exceções.
Observação
O DefaultProblemDetailsWriter suporta os seguintes tipos de mídia no cabeçalho de solicitação Accept:
application/jsonapplication/problem+json- Tipos curinga, como
*/*eapplication/*
Tipos de mídia não JSON, como application/xml ou text/html, não têm suporte e disparam o comportamento de fallback.
O exemplo a seguir é semelhante ao anterior, exceto pelo fato de chamar o Status Code Pages middleware.
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddProblemDetails();
var app = builder.Build();
app.UseStatusCodePages(statusCodeHandlerApp =>
{
statusCodeHandlerApp.Run(async httpContext =>
{
var pds = httpContext.RequestServices.GetService<IProblemDetailsService>();
if (pds == null
|| !await pds.TryWriteAsync(new() { HttpContext = httpContext }))
{
// Fallback behavior
await httpContext.Response.WriteAsync("Fallback: An error occurred.");
}
});
});
app.MapGet("/users/{id:int}", (int id) =>
{
return id <= 0 ? Results.BadRequest() : Results.Ok(new User(id));
});
app.MapGet("/", () => "Test by calling /users/{id:int}");
app.Run();
public record User(int Id);
Recursos adicionais de tratamento de erros
Migração de controladores para APIs mínimas
Se você estiver migrando de APIs baseadas em controlador para APIs mínimas:
- Substitua filtros de ação por filtros de endpoint ou middleware
- Substituir validação de modelo por validação manual ou associação personalizada
- Substituir filtros de exceção por middleware de tratamento de exceções
-
Configurar detalhes do problema usando
AddProblemDetails()para respostas de erro consistentes
Quando usar o tratamento de erros baseado em controlador
Considere APIs baseadas em controlador se precisar.
- Cenários complexos de validação de modelo
- Tratamento centralizado de exceções entre vários controladores
- Controle refinado sobre a formatação de resposta de erro
- Integração com recursos do MVC, como filtros e convenções
Para obter informações detalhadas sobre o tratamento de erros baseados em controlador, incluindo erros de validação, personalização de detalhes do problema e filtros de exceção, consulte as seções da guia Controladores .