Delen via


Fouten in ASP.NET Core-API's verwerken

Opmerking

Dit is niet de nieuwste versie van dit artikel. Zie de .NET 9-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-ondersteuningsbeleid voor meer informatie. Zie de .NET 9-versie van dit artikel voor de huidige release.

Belangrijk

Deze informatie heeft betrekking op een pre-releaseproduct dat aanzienlijk kan worden gewijzigd voordat het commercieel wordt uitgebracht. Microsoft geeft geen garanties, uitdrukkelijk of impliciet, met betrekking tot de informatie die hier wordt verstrekt.

Zie de .NET 9-versie van dit artikel voor de huidige release.

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 om documentatie te bekijken voor api's op basis van een controller. Zie BlazorFouten afhandelen in ASP.NET Core-apps Blazor voor hulp bij het afhandelen van fouten.

Uitzonderingspagina voor ontwikkelaars

Op de uitzonderingspagina voor ontwikkelaars wordt gedetailleerde informatie weergegeven over niet-verwerkte aanvraag-uitzonderingen. Het maakt gebruik DeveloperExceptionPageMiddleware van het vastleggen van synchrone en asynchrone uitzonderingen van de HTTP-pijplijn en voor het genereren van foutreacties. De uitzonderingspagina voor ontwikkelaars wordt vroeg in de middleware-pijplijn uitgevoerd, zodat er niet-verwerkte uitzonderingen kunnen worden ondervangen die worden gegenereerd in middleware die volgt.

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

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

Waarschuwing

Schakel de uitzonderingspagina voor ontwikkelaars alleen in als de app wordt uitgevoerd in de ontwikkelomgeving. 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 Logboekregistratie 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:

Uitzonderingspagina voor ontwikkelaars om elk geselecteerd tabblad weer te geven.

Als reactie op een aanvraag met een Accept: text/plain 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

De uitzonderingspagina voor ontwikkelaars in een minimale API bekijken:

  • Voer de voorbeeld-app uit in de ontwikkelomgeving.
  • Ga naar het /exception 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 /exception 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 Middleware voor uitzonderingshandler om een foutpayload te produceren.

Als u de aanroep wilt configureren, roept u het Exception Handler Middlewareaan UseExceptionHandler. De volgende code wijzigt bijvoorbeeld de app om te reageren met een RFC 7807-compatibele nettolading 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

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 /users eindpunt produceert 200 OK met een json weergave van User wanneer id deze groter is dan 0, anders een 400 BAD REQUEST statuscode zonder antwoordtekst. Zie Antwoorden maken in minimale API-apps voor meer informatie over het maken van een antwoord.

De Status Code Pages middleware kan worden geconfigureerd om een algemene hoofdtekstinhoud te produceren, wanneer deze leeg is, voor alle HTTP-clientreacties (400-499) of serverreacties.500 -599 De middleware wordt geconfigureerd door de useStatusCodePages-extensiemethode aan te roepen.

In het volgende voorbeeld wordt de app bijvoorbeeld gewijzigd om te reageren met een rfC 7807-compatibele nettolading naar de client voor alle client- en serverreacties, inclusief routeringsfouten (bijvoorbeeld 404 NOT FOUND). 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 met probleemdetails implementeert de IProblemDetailsService interface, die ondersteuning biedt voor het maken van probleemdetails in ASP.NET Core. De AddProblemDetails(IServiceCollection) extensiemethode voor IServiceCollection het registreren van de standaard IProblemDetailsService implementatie.

In ASP.NET Core-apps genereert de volgende middleware http-antwoorden wanneer AddProblemDetails deze worden aangeroepen, behalve wanneer de Accept AANVRAAG-HTTP-header geen van de inhoudstypen bevat die worden ondersteund door de geregistreerde IProblemDetailsWriter (standaardinstelling: application/json):

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 AddProblemDetails 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 AddProblemDetails voor meer informatie over het gebruik

Terugval IProblemDetailsService

Retourneert in de volgende code httpContext.Response.WriteAsync("Fallback: An error occurred.") een fout als de IProblemDetailsService implementatie geen 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();

De voorgaande code:

  • Hiermee schrijft u een foutbericht met de terugvalcode als de problemDetailsService terugvalcode een ProblemDetails. Bijvoorbeeld een eindpunt waarbij de header Aanvraag accepteren een mediatype opgeeft dat het DefaulProblemDetailsWriter niet ondersteunt.
  • Maakt gebruik van de Exception Handler Middleware.

Het volgende voorbeeld is vergelijkbaar met het voorgaande, behalve dat het de 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);

Aanvullende functies voor foutafhandeling

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 AddProblemDetails() consistente foutreacties

Wanneer gebruikt u foutafhandeling op basis van controller

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 foutreacties
  • 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