Remarque
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de vous connecter ou de modifier des répertoires.
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de modifier des répertoires.
Note
Ceci n’est pas la dernière version de cet article. Pour la version actuelle, consultez la version .NET 10 de cet article.
Avertissement
Cette version de ASP.NET Core n’est plus prise en charge. Pour plus d’informations, consultez la politique de support de .NET et .NET Core. Pour la version actuelle, consultez la version .NET 10 de cet article.
Cet article explique comment gérer les erreurs dans ASP.NET Core API. La documentation relative aux API minimales est sélectionnée. Pour afficher la documentation relative aux API basées sur le contrôleur, sélectionnez l’onglet Controllers. Pour obtenir des instructions de gestion des erreurs Blazor, consultez les erreurs Handle dans les applications ASP.NET Core Blazor.
Page d’exception du développeur
La Page d’exception du développeur affiche des informations détaillées sur les exceptions des requêtes non prises en charge. Il utilise DeveloperExceptionPageMiddleware pour capturer des exceptions synchrones et asynchrones à partir du pipeline HTTP et pour générer des réponses d’erreur. La page d'exception du développeur s'exécute tôt dans le pipeline d'intergiciels, afin de pouvoir intercepter les exceptions non gérées levées dans les intergiciels suivants.
ASP.NET Core applications activent la page d’exception de développeur par défaut lorsque les deux :
- En cours d’exécution dans l’environnement
Development. - L’application a été créée avec les modèles actuels, c’est-à-dire à l’aide de WebApplication.CreateBuilder.
Les applications créées à l’aide de modèles antérieurs, c’est-à-dire à l’aide de WebHost.CreateDefaultBuilder, peuvent activer la page d’exception de développeur en appelant app.UseDeveloperExceptionPage.
Avertissement
N’activez pas la page d’exception du développeur, sauf si l’application s’exécute dans l’environnementDevelopment. Ne partagez pas d’informations d’exception détaillées publiquement lorsque l’application s’exécute en production. Pour plus d’informations sur la configuration des environnements, consultez ASP.NET Core environnements d’exécution.
La page d’exception du développeur peut inclure les informations suivantes sur l’exception et la demande :
- Trace de pile
- Paramètres de chaîne de requête, le cas échéant
- Cookies, le cas échéant
- headers
- Métadonnées de point de terminaison, le cas échéant
La page d’exception du développeur n’est pas garantie de fournir des informations. Utilisez la journalisation pour obtenir des informations complètes sur l’erreur.
L’image suivante montre un exemple de page d’exception de développeur avec animation pour afficher les onglets et les informations affichées :
En réponse à une demande avec un en-tête Accept: text/plain, la page d’exception du développeur retourne du texte brut au lieu de HTML. Par exemple:
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
Pour afficher la page d’exception du développeur dans une API minimale :
- Exécutez l’exemple d’application dans l’environnement
Development. - Accédez au
/exceptionpoint de terminaison.
Cette section fait référence à l’exemple d’application suivant pour illustrer les méthodes de gestion des exceptions dans une API minimale. Elle lève une exception lorsque le point de terminaison /exception est demandé :
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();
Gestionnaire d’exceptions
Dans les environnements non de développement, utilisez l’intergiciel du gestionnaire d’exceptions pour produire une charge utile d’erreur.
Pour configurer le exception handler middleware, appelez UseExceptionHandler. Par exemple, le code suivant modifie l’application pour répondre avec une charge utile conforme RFC 7807 au client. Pour plus d’informations, consultez la section Détails du problème plus loin dans cet article.
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();
Réponses d’erreur client et serveur
Considérez l’application API minimale suivante.
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);
Le point de terminaison /users produit 200 OK avec une représentation json de User lorsque id est supérieur à 0, sinon renvoie un code d’état 400 BAD REQUEST sans corps de réponse. Pour plus d’informations sur la création d’une réponse, consultez Créer des réponses dans les applications API minimales.
Le Status Code Pages middleware peut être configuré pour produire un contenu de corps commun, lorsqu’elles sont vides, pour toutes les réponses HTTP côté client (400-499) ou côté serveur (500 -599). L’intergiciel est configuré en appelant la méthode d’extension UseStatusCodePages .
Par exemple, l’exemple suivant modifie l’application pour répondre avec une charge utile conforme RFC 7807 au client pour toutes les réponses client et serveur, y compris les erreurs de routage (par exemple). 404 NOT FOUND Pour plus d’informations, consultez la section Détails du problème .
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);
Détails du problème
Les détails du problème ne sont pas le seul format de réponse à décrire une erreur d’API HTTP. Toutefois, ils sont couramment utilisés pour signaler des erreurs pour les API HTTP.
Le service détails du problème implémente l’interface IProblemDetailsService, qui prend en charge la création de détails de problème dans ASP.NET Core. La méthode d’extension AddProblemDetails(IServiceCollection) sur IServiceCollection enregistre l’implémentation IProblemDetailsService par défaut.
Dans les applications ASP.NET Core, l'intergiciel suivant génère des réponses HTTP avec des détails de problème lorsque
- ExceptionHandlerMiddleware : génère une réponse sur les détails du problème lorsqu’un gestionnaire personnalisé n’est pas défini.
- StatusCodePagesMiddleware : génère une réponse de détails de problème par défaut.
-
DeveloperExceptionPageMiddleware : génère une réponse sur les détails du problème lors du développement lorsque l’en-tête HTTP de la requête
Acceptn’inclut pastext/html.
Les applications d’API minimales peuvent être configurées pour générer une réponse de type Problem Details pour toutes les réponses d’erreur HTTP côté client et côté serveur qui ne comportent pas encore de corps de réponse à l’aide de la méthode d’extension AddProblemDetails.
Le code suivant configure l’application pour générer les détails du problème :
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);
Pour plus d’informations sur l’utilisation AddProblemDetails, consultez Détails du problème
Secours IProblemDetailsService
Dans le code suivant, httpContext.Response.WriteAsync("Fallback: An error occurred.") retourne une erreur si l’implémentation IProblemDetailsService n’est pas en mesure de générer un 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();
Code précédent :
- Écrit un message d’erreur avec le code de repli si le
problemDetailsServicen’est pas en mesure d’écrire unProblemDetails. Par exemple, un point de terminaison où l’en-tête de requête Accept spécifie un type de média que leDefaultProblemDetailsWriterne prend pas en charge. - Utilise l’intergiciel du gestionnaire d’exceptions.
Note
Le DefaultProblemDetailsWriter prend en charge les types de média suivants dans l’en-tête de requête Accept :
application/jsonapplication/problem+json- Types génériques tels que
*/*etapplication/*
Les types de média non-JSON, tels que application/xml ou text/html, ne sont pas pris en charge et déclenchent le mécanisme de secours.
L’exemple suivant est similaire à l’exemple précédent, sauf qu’il appelle le 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);
Fonctionnalités supplémentaires de gestion des erreurs
Migration de contrôleurs vers des API minimales
Si vous migrez des API basées sur le contrôleur vers des API minimales :
- Remplacer les filtres d’action par des filtres de point de terminaison ou un intergiciel
- Remplacer la validation du modèle par une validation manuelle ou une liaison personnalisée
- Remplacer les filtres d’exceptions par le middleware de gestion des exceptions
-
Configurer les détails du problème à l’aide de
AddProblemDetails()pour obtenir des réponses d’erreur cohérentes
Quand utiliser la gestion des erreurs basée sur le contrôleur
Envisagez les API basées sur le contrôleur si vous avez besoin des éléments suivants :
- Scénarios de validation de modèle complexes
- Gestion centralisée des exceptions sur plusieurs contrôleurs
- Contrôle précis sur la mise en forme de réponse aux erreurs
- Intégration à des fonctionnalités MVC telles que des filtres et des conventions
Pour plus d’informations sur la gestion des erreurs basée sur le contrôleur, notamment les erreurs de validation, la personnalisation des détails du problème et les filtres d’exceptions, consultez les sections de l’onglet Contrôleurs .