Delen via


Fouten in ASP.NET Core API's verwerken

Opmerking

Dit is niet de nieuwste versie van dit artikel. Zie de .NET 10-versie van dit artikel voor de huidige release.

Waarschuwing

Deze versie van ASP.NET Core wordt niet meer ondersteund. Zie het .NET en .NET Core Support Policy voor meer informatie. Zie de .NET 10-versie van dit artikel voor de huidige release.

  • Minimale APIs
  • Regelaars

In dit artikel wordt beschreven hoe u fouten in ASP.NET Core API's kunt verwerken. Documentatie voor minimale API's is geselecteerd. Selecteer het tabblad Controllers voor documentatie voor api's op basis van een controller. Zie Blazor voor foutafhandelingsrichtlijnen.

Uitzonderingspagina voor ontwikkelaars

Op de uitzonderingspagina voor ontwikkelaars wordt gedetailleerde informatie weergegeven over niet-verwerkte aanvraag-uitzonderingen. Het maakt gebruik van het vastleggen van synchrone en asynchrone uitzonderingen van de HTTP-pijplijn en voor het genereren van foutreacties. De foutpagina voor ontwikkelaars draait vroeg in de middleware-pijplijn, zodat niet-verwerkte uitzonderingen kunnen worden opgevangen die optreden in de daaropvolgende middleware.

ASP.NET Core apps de uitzonderingspagina voor ontwikkelaars standaard inschakelen wanneer beide:

  • Wordt uitgevoerd in de omgeving.
  • De app is gemaakt met de huidige sjablonen, dat wil gezegd met behulp van .

Apps die zijn gemaakt met behulp van eerdere sjablonen, kunnen de uitzonderingspagina voor ontwikkelaars inschakelen door aan te roepen .

Waarschuwing

Schakel de uitzonderingspagina voor ontwikkelaars alleen in als de app wordt uitgevoerd in de omgeving. Deel geen gedetailleerde uitzonderingsgegevens openbaar wanneer de app in productie wordt uitgevoerd. Zie ASP.NET Core runtime-omgevingen voor meer informatie over het configureren van omgevingen.

De uitzonderingspagina voor ontwikkelaars kan de volgende informatie bevatten over de uitzondering en de aanvraag:

  • Stacktracering
  • Queryreeksparameters, indien van toepassing
  • Cookies, indien van toepassing
  • Headers
  • Eindpuntmetagegevens, indien van toepassing

De uitzonderingspagina voor ontwikkelaars is niet gegarandeerd informatie te verstrekken. Gebruik Logging voor volledige foutinformatie.

In de volgende afbeelding ziet u een voorbeeld van een uitzonderingspagina voor ontwikkelaars met animatie om de tabbladen en de weergegeven informatie weer te geven:

Geanimeerde uitzonderingspagina voor ontwikkelaars die elke geselecteerde tab laat zien.

Als reactie op een aanvraag met een header retourneert de uitzonderingspagina voor ontwikkelaars tekst zonder opmaak in plaats van HTML. Voorbeeld:

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
  • Minimale API's
  • Controllers

De uitzonderingspagina voor ontwikkelaars in een minimale API bekijken:

  • Voer de voorbeeld-app uit in de omgeving.
  • Ga naar het eindpunt.

Deze sectie verwijst naar de volgende voorbeeld-app om manieren te demonstreren voor het afhandelen van uitzonderingen in een minimale API. Er wordt een uitzondering gegenereerd wanneer het eindpunt wordt aangevraagd:

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

Uitzonderingshandler

Gebruik in niet-ontwikkelomgevingen de Uitzonderingshandler Middleware om een foutbericht te produceren.

  • Minimale API's
  • Besturingseenheden

Om de configuratie aan te passen, belt u . De volgende code wijzigt bijvoorbeeld de app om te reageren met een RFC 7807-compliant payload naar de client. Zie de sectie Probleemdetails verderop in dit artikel voor meer informatie.

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

Antwoorden op client- en serverfouten

  • Minimale API's
  • Controllers

Houd rekening met de volgende minimale 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);

Het eindpunt produceert met een weergave van wanneer deze groter is dan , anders een statuscode zonder antwoordtekst. Zie Antwoorden maken in minimale API-apps voor meer informatie over het maken van een antwoord.

De () kan worden geconfigureerd om een algemene inhoud voor de hoofdtekst te genereren wanneer deze leeg is, voor alle HTTP-clientreacties () of serverreacties (). De middleware wordt geconfigureerd door de useStatusCodePages-extensiemethode aan te roepen.

In het volgende voorbeeld wordt de app gewijzigd om te reageren met een RFC 7807-compatibele payload naar de client voor alle client- en serverreacties, inclusief routeringsfouten. Zie de sectie Probleemdetails voor meer informatie.

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

Details van probleem

Probleemdetails zijn niet de enige antwoordindeling voor het beschrijven van een HTTP-API-fout. Ze worden echter vaak gebruikt om fouten voor HTTP-API's te rapporteren.

De service voor probleemdetails implementeert de interface IProblemDetailsService, die ondersteuning biedt voor het maken van probleemdetails in ASP.NET Core. De extensiemethode registreert de standaardimplementatie.

In ASP.NET Core-apps genereert de volgende middleware HTTP-probleemdetaillantwoorden wanneer AddProblemDetails wordt aangeroepen, behalve wanneer de HTTP-header van het Accept verzoek geen van de inhoudstypen bevat die worden ondersteund door de geregistreerde IProblemDetailsWriter (standaard: application/json):

  • : Genereert een antwoord met probleemdetails wanneer er geen aangepaste handler is gedefinieerd.
  • : genereert standaard een antwoord met details van het probleem.
  • Genereert een antwoord met probleemdetails tijdens ontwikkeling wanneer de HTTP-header van een aanvraag ontbreekt.
  • Minimale API's
  • Controllers

Minimale API-apps kunnen worden geconfigureerd om antwoord op probleemdetails te genereren voor alle HTTP-client- en serverfoutreacties die nog geen hoofdtekstinhoud hebben met behulp van de extensiemethode.

Met de volgende code wordt de app geconfigureerd voor het genereren van probleemdetails:

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

Zie de probleemdetails voor meer informatie over het gebruik.

Fallback IProblemDetailsService

In de volgende code retourneert een fout als de geen kan genereren.

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

De voorgaande code:

  • Schrijft een foutbericht met de terugvalcode als niet in staat is om een bestand te schrijven. Bijvoorbeeld een eindpunt waarbij de header Aanvraag accepteren een mediatype opgeeft dat het niet ondersteunt.
  • Maakt gebruik van de Exception Handler Middleware.

Opmerking

De ondersteuning biedt de volgende mediatypen in de request-koptekst:

  • application/json
  • application/problem+json
  • Jokertekentypen zoals en

Niet-JSON-mediatypen, zoals of , worden niet ondersteund en activeren het terugvalgedrag.

Het volgende voorbeeld is vergelijkbaar met het voorgaande, behalve dat het de functie aanroept.

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

Aanvullende functies voor foutafhandeling

  • Minimale API's
  • Controllers

Migratie van controllers naar minimale API's

Als u migreert van api's op basis van een controller naar minimale API's:

  1. Actiefilters vervangen door eindpuntfilters of middleware
  2. Modelvalidatie vervangen door handmatige validatie of aangepaste binding
  3. Uitzonderingsfilters vervangen door middleware voor uitzonderingsafhandeling
  4. Probleemdetails configureren voor consistente foutreacties

Wanneer gebruikt men controller-gebaseerde foutafhandeling?

Overweeg api's op basis van een controller als u het volgende nodig hebt:

  • Complexe modelvalidatiescenario's
  • Gecentraliseerde verwerking van uitzonderingen op meerdere controllers
  • Fijnmazige controle over de opmaak van foutmeldingen
  • Integratie met MVC-functies zoals filters en conventies

Zie de tabbladsecties Controllers voor gedetailleerde informatie over foutafhandeling op basis van controller, waaronder validatiefouten, aanpassing van probleemdetails en uitzonderingsfilters .

Aanvullende bronnen