Behandeln von Fehlern in Minimal-API-Apps
Hinweis
Dies ist nicht die neueste Version dieses Artikels. Informationen zum aktuellen Release finden Sie in der .NET 8-Version dieses Artikels.
Warnung
Diese Version von ASP.NET Core wird nicht mehr unterstützt. Weitere Informationen finden Sie in der Supportrichtlinie für .NET und .NET Core. Informationen zum aktuellen Release finden Sie in der .NET 8-Version dieses Artikels.
Wichtig
Diese Informationen beziehen sich auf ein Vorabversionsprodukt, das vor der kommerziellen Freigabe möglicherweise noch wesentlichen Änderungen unterliegt. Microsoft gibt keine Garantie, weder ausdrücklich noch impliziert, hinsichtlich der hier bereitgestellten Informationen.
Informationen zum aktuellen Release finden Sie in der .NET 8-Version dieses Artikels.
Mit Beiträgen von David Acker
In diesem Artikel wird beschrieben, wie Sie Fehler in Minimal-API-Apps behandeln. Informationen zur Fehlerbehandlung in controllerbasierten APIs finden Sie unter Behandeln von Fehlern in ASP.NET Core und Behandeln von Fehlern in ASP.NET Core-controllerbasierten Web-APIs.
Ausnahmen
In einer Minimal-API-App gibt es zwei verschiedene integrierte und zentralisierte Verfahren zum Behandeln von Ausnahmefehlern:
- Middleware für Entwicklerausnahmeseite (Nur für die Verwendung in der Entwicklungsumgebung.)
- Middleware für Ausnahmehandler
In diesem Abschnitt wird auf die folgende Beispiel-App verwiesen, um Möglichkeiten zum Behandeln von Ausnahmen in einer Minimal-API zu veranschaulichen. Sie löst eine Ausnahme aus, wenn der Endpunkt /exception
angefordert wird:
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();
Seite mit Ausnahmen für Entwickler
Die Seite mit Ausnahmen für Entwickler enthält ausführliche Informationen zu unbehandelten Anforderungsausnahmen. Es verwendet DeveloperExceptionPageMiddleware, um synchrone und asynchrone Ausnahmen aus der HTTP-Pipeline zu erfassen und um Fehlerantworten zu generieren. Die Seite mit Ausnahmen für Entwickler wird früh in der Middlewarepipeline ausgeführt, sodass in der nachfolgenden Middleware ausgelöste unbehandelte Ausnahmen abgefangen werden.
ASP.NET Core-Apps aktivieren standardmäßig die Seite mit Ausnahmen für Entwickler, wenn die folgenden Aussagen beide zutreffen:
- Die Ausführung erfolgt in der Entwicklungsumgebung.
- Die App wurde mit den aktuellen Vorlagen erstellt, d. h. mithilfe von WebApplication.CreateBuilder.
Apps, die mit früheren Vorlagen erstellt wurden, d. h. mithilfe von WebHost.CreateDefaultBuilder, können die Seite mit Ausnahmen für Entwickler durch Aufrufen von app.UseDeveloperExceptionPage
aktivieren.
Warnung
Aktivieren Sie die Seite für Entwicklerausnahmen nur, wenn die App in der Entwicklungsumgebung ausgeführt wird. Wenn die App in der Produktionsumgebung ausgeführt wird, sollten Sie keine detaillierten Ausnahmeinformationen öffentlich teilen. Weitere Informationen zum Konfigurieren der Umgebung finden Sie unter Verwenden mehrerer Umgebungen in ASP.NET Core.
Die Seite mit Ausnahmen für Entwickler kann die folgenden Informationen zu der Ausnahme und der Anforderung enthalten:
- Stapelüberwachung
- Abfragezeichenfolgeparameter, sofern vorhanden
- Cookies (sofern vorhanden)
- Headers
- Endpunktmetadaten (falls vorhanden)
Es ist nicht garantiert, dass auf der Seite mit Ausnahmen für Entwickler Informationen angezeigt werden. Vollständige Informationen zu Fehlern finden Sie unter Protokollierung.
Die folgende Abbildung zeigt eine Beispielseite für Entwicklerausnahmen mit Animation, um die Registerkarten und die angezeigten Informationen anzuzeigen:
Als Reaktion auf eine Anforderung mit einem Accept: text/plain
-Header gibt die Seite mit Ausnahmen für Entwickler nur Text anstelle von HTML zurück. Zum Beispiel:
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
So gelangen Sie zur Seite mit Ausnahmen für Entwickler:
- Führen Sie die Beispiel-App in der Entwicklungsumgebung aus.
- Wechseln Sie zum
/exception
-Endpunkt.
Ausnahmehandler
In Nicht-Entwicklungsumgebungen kann Middleware zur Ausnahmebehandlung verwendet werden, um Fehlernutzdaten zu generieren. Rufen Sie UseExceptionHandler auf, um Exception Handler Middleware
zu konfigurieren.
Der folgende Code ändert die App beispielsweise so, dass sie dem Client mit RFC 7807-konformen Nutzdaten antwortet. Weitere Informationen finden Sie im Abschnitt Problemdetails weiter unten in diesem Artikel.
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();
Client- und Serverfehlerantworten
Betrachten Sie die folgende Minimal-API-App.
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);
Der /users
-Endpunkt generiert 200 OK
mit einer json
-Darstellung von User
, wenn id
größer als 0
ist, und andernfalls den Statuscode 400 BAD REQUEST
ohne Antworttext. Weitere Informationen zum Erstellen einer Antwort finden Sie unter Erstellen von Antworten in Minimal-API-Apps.
Status Code Pages middleware
kann so konfiguriert werden, dass für alle HTTP-Antworten vom Client (400
-499
) oder Server (500
-599
) ein allgemeiner Textinhalt erzeugt wird, wenn er leer ist. Die Middleware wird durch Aufrufen der UseStatusCodePages-Erweiterungsmethode konfiguriert.
Im folgenden Beispiel wird die App beispielsweise so geändert, dass sie dem Client mit RFC 7807-konformen Nutzdaten für alle Client- und Serverantworten reagiert, einschließlich Routingfehlern (z. B. 404 NOT FOUND
). Weitere Informationen finden Sie im Abschnitt zu Problemdetails.
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);
Problemdetails
Problemdetails sind nicht das einzige Antwortformat zur Beschreibung eines HTTP-API-Fehlers, sie werden jedoch häufig verwendet, um Fehler für HTTP-APIs zu melden.
Der Dienst für Problemdetails implementiert die IProblemDetailsService-Schnittstelle, die das Erstellen von Problemdetails in ASP.NET Core unterstützt. Die Erweiterungsmethode AddProblemDetails(IServiceCollection) in IServiceCollection registriert die Standardimplementierung von IProblemDetailsService
.
In ASP.NET Core-Apps generiert die folgende Middleware HTTP-Antworten mit Problemdetails, wenn AddProblemDetails
aufgerufen wird. Dies gilt jedoch nicht, wenn der Accept
-HTTP-Anforderungsheader keinen der vom registrierten IProblemDetailsWriter unterstützten Inhaltstyp enthält (Standard: application/json
):
- ExceptionHandlerMiddleware generiert eine Problemdetailantwort, wenn kein benutzerdefinierter Handler definiert ist.
- StatusCodePagesMiddleware generiert standardmäßig eine Problemdetailantwort.
- DeveloperExceptionPageMiddleware generiert eine Problemdetailantwort während der Entwicklungsphase, wenn der
Accept
-HTTP-Anforderungsheader nichttext/html
enthält.
Minimal-API-Apps können mithilfe der AddProblemDetails
-Erweiterungsmethode so konfiguriert werden, dass sie eine Antwort mit Problemdetails für alle HTTP-Antworten zu Client- und Serverfehlern generieren, die noch keinen Textinhalt aufweisen.
Mit dem folgenden Code wird die App so konfiguriert, dass Problemdetails generiert werden:
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);
Weitere Informationen zur Verwendung von AddProblemDetails
finden Sie unter Problemdetails.
IProblemDetailsService-Fallback
Im folgenden Code gibt httpContext.Response.WriteAsync("Fallback: An error occurred.")
einen Fehler zurück, wenn die Implementierung von IProblemDetailsService kein ProblemDetails-Element generieren kann:
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();
Der obige Code:
- Schreibt eine Fehlermeldung mit dem Fallbackcode, wenn
ProblemDetails
nicht vonproblemDetailsService
geschrieben werden kann. Beispielsweise ein Endpunkt, bei dem der Anforderungsheader für die Annahme einen Medientyp angibt, der vonDefaulProblemDetailsWriter
nicht unterstützt wird. - Nutzt die Middleware für Ausnahmehandler.
Das folgende Beispiel ähnelt dem vorherigen, mit der Ausnahme, dass Status Code Pages middleware
aufgerufen wird.
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);
In diesem Artikel wird beschrieben, wie Sie Fehler in Minimal-API-Apps behandeln.
Ausnahmen
In einer Minimal-API-App gibt es zwei verschiedene integrierte und zentralisierte Verfahren zum Behandeln von Ausnahmefehlern:
- Middleware für Entwicklerausnahmeseite (Nur für die Verwendung in der Entwicklungsumgebung.)
- Middleware für Ausnahmehandler
In diesem Abschnitt wird auf die folgende Minimal-API-App verwiesen, um Möglichkeiten zum Behandeln von Ausnahmen zu veranschaulichen. Sie löst eine Ausnahme aus, wenn der Endpunkt /exception
angefordert wird:
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
app.Map("/exception", ()
=> { throw new InvalidOperationException("Sample Exception"); });
app.Run();
Seite mit Ausnahmen für Entwickler
Auf der Seite mit Entwicklerausnahmen werden detaillierte Stapelüberwachungen für Serverfehler angezeigt. Es verwendet DeveloperExceptionPageMiddleware, um synchrone und asynchrone Ausnahmen aus der HTTP-Pipeline zu erfassen und um Fehlerantworten zu generieren.
ASP.NET Core-Apps aktivieren standardmäßig die Seite mit Ausnahmen für Entwickler, wenn die folgenden Aussagen beide zutreffen:
- Die Ausführung erfolgt in der Entwicklungsumgebung.
- Die App verwendet WebApplication.CreateBuilder.
Weitere Informationen zum Konfigurieren von Middleware finden Sie unter Middleware in Minimal-API-Apps.
Wenn Developer Exception Page
bei der obigen Minimal-API-App einen Ausnahmefehler erkennt, generiert sie eine Nur-Text-Standardantwort, die dem folgenden Beispiel ähnelt:
HTTP/1.1 500 Internal Server Error
Content-Type: text/plain; charset=utf-8
Date: Thu, 27 Oct 2022 18:00:59 GMT
Server: Kestrel
Transfer-Encoding: chunked
System.InvalidOperationException: Sample Exception
at Program.<>c.<<Main>$>b__0_1() in ....:line 17
at lambda_method2(Closure, Object, HttpContext)
at Microsoft.AspNetCore.Routing.EndpointMiddleware.Invoke(HttpContext httpContext)
--- End of stack trace from previous location ---
at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddlewareImpl.Invoke(HttpContext context)
HEADERS
=======
Accept: */*
Connection: keep-alive
Host: localhost:5239
Accept-Encoding: gzip, deflate, br
Warnung
Aktivieren Sie die Seite für Entwicklerausnahmen nur, wenn die App in der Entwicklungsumgebung ausgeführt wird. Wenn die App in der Produktionsumgebung ausgeführt wird, sollten Sie keine detaillierten Ausnahmeinformationen öffentlich teilen. Weitere Informationen zum Konfigurieren der Umgebung finden Sie unter Verwenden mehrerer Umgebungen in ASP.NET Core.
Ausnahmehandler
In Nicht-Entwicklungsumgebungen kann Middleware zur Ausnahmebehandlung verwendet werden, um Fehlernutzdaten zu generieren. Rufen Sie UseExceptionHandler auf, um Exception Handler Middleware
zu konfigurieren.
Der folgende Code ändert die App beispielsweise so, dass sie dem Client mit RFC 7807-konformen Nutzdaten antwortet. Weitere Informationen finden Sie im Abschnitt zu Problemdetails.
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
app.UseExceptionHandler(exceptionHandlerApp
=> exceptionHandlerApp.Run(async context
=> await Results.Problem()
.ExecuteAsync(context)));
app.Map("/exception", ()
=> { throw new InvalidOperationException("Sample Exception"); });
app.Run();
Client- und Serverfehlerantworten
Betrachten Sie die folgende Minimal-API-App.
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
app.Map("/users/{id:int}", (int id)
=> id <= 0 ? Results.BadRequest() : Results.Ok(new User(id)) );
app.Run();
public record User(int Id);
Der /users
-Endpunkt generiert 200 OK
mit einer json
-Darstellung von User
, wenn id
größer als 0
ist, und andernfalls den Statuscode 400 BAD REQUEST
ohne Antworttext. Weitere Informationen zum Erstellen einer Antwort finden Sie unter Erstellen von Antworten in Minimal-API-Apps.
Status Code Pages middleware
kann so konfiguriert werden, dass für alle HTTP-Antworten vom Client (400
-499
) oder Server (500
-599
) ein allgemeiner Textinhalt erzeugt wird, wenn er leer ist. Die Middleware wird durch Aufrufen der UseStatusCodePages-Erweiterungsmethode konfiguriert.
Im folgenden Beispiel wird die App beispielsweise so geändert, dass sie dem Client mit RFC 7807-konformen Nutzdaten für alle Client- und Serverantworten reagiert, einschließlich Routingfehlern (z. B. 404 NOT FOUND
). Weitere Informationen finden Sie im Abschnitt zu Problemdetails.
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.Map("/users/{id:int}", (int id)
=> id <= 0 ? Results.BadRequest() : Results.Ok(new User(id)) );
app.Run();
public record User(int Id);
Problemdetails
Problemdetails sind nicht das einzige Antwortformat zur Beschreibung eines HTTP-API-Fehlers, sie werden jedoch häufig verwendet, um Fehler für HTTP-APIs zu melden.
Der Dienst für Problemdetails implementiert die IProblemDetailsService-Schnittstelle, die das Erstellen von Problemdetails in ASP.NET Core unterstützt. Die Erweiterungsmethode AddProblemDetails(IServiceCollection) in IServiceCollection registriert die Standardimplementierung von IProblemDetailsService
.
In ASP.NET Core-Apps generiert die folgende Middleware HTTP-Antworten mit Problemdetails, wenn AddProblemDetails
aufgerufen wird. Dies gilt jedoch nicht, wenn der Accept
-HTTP-Anforderungsheader keinen der vom registrierten IProblemDetailsWriter unterstützten Inhaltstyp enthält (Standard: application/json
):
- ExceptionHandlerMiddleware generiert eine Problemdetailantwort, wenn kein benutzerdefinierter Handler definiert ist.
- StatusCodePagesMiddleware generiert standardmäßig eine Problemdetailantwort.
- DeveloperExceptionPageMiddleware generiert eine Problemdetailantwort während der Entwicklungsphase, wenn der
Accept
-HTTP-Anforderungsheader nichttext/html
enthält.
Minimal-API-Apps können mithilfe der AddProblemDetails
-Erweiterungsmethode so konfiguriert werden, dass sie eine Antwort mit Problemdetails für alle HTTP-Antworten zu Client- und Serverfehlern generieren, die noch keinen Textinhalt aufweisen.
Mit dem folgenden Code wird die App so konfiguriert, dass Problemdetails generiert werden:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddProblemDetails();
var app = builder.Build();
app.UseExceptionHandler();
app.UseStatusCodePages();
app.Map("/users/{id:int}", (int id)
=> id <= 0 ? Results.BadRequest() : Results.Ok(new User(id)) );
app.Map("/exception", ()
=> { throw new InvalidOperationException("Sample Exception"); });
app.Run();
Weitere Informationen zur Verwendung von AddProblemDetails
finden Sie unter Problemdetails.