Megosztás a következőn keresztül:


ASP.NET Core API-k hibáinak kezelése

Megjegyzés:

Ez nem a cikk legújabb verziója. Az aktuális kiadásról a cikk .NET 10-es verziójában olvashat.

Figyelmeztetés

A ASP.NET Core ezen verziója már nem támogatott. További információt a .NET és a .NET Core támogatási szabályzatában talál. A jelen cikk .NET 9-es verzióját lásd az aktuális kiadásért .

Ez a cikk a ASP.NET Core API-k hibáinak kezelését ismerteti. A minimális API-k dokumentációja ki van választva. A vezérlőalapú API-k dokumentációjának megtekintéséhez válassza a Vezérlők lapot. A Blazor hibakezelési útmutatót a ASP.NET Core-alkalmazások Blazor hibáinak kezelése című témakörben talál.

Fejlesztői kivétel lap

A Fejlesztői kivétel lap részletes információkat jelenít meg a nem kezelt kérelmek kivételeiről. A HTTP-folyamat szinkron és aszinkron kivételeinek rögzítésére és hibaválaszok létrehozására használja DeveloperExceptionPageMiddleware . A fejlesztői kivételoldal a köztes szoftver folyamatának korai szakaszában fut, hogy a következő köztes szoftverben megjelenő kezeletlen kivételeket észlelhesse.

ASP.NET Core-alkalmazások alapértelmezés szerint engedélyezik a fejlesztői kivételoldalt, ha mindkettő:

A korábbi sablonok használatával létrehozott alkalmazások, vagyis a használatával WebHost.CreateDefaultBuilder, hívással engedélyezhetik a fejlesztői kivételoldalt app.UseDeveloperExceptionPage.

Figyelmeztetés

Csak akkor engedélyezze a fejlesztői kivételoldalt, ha az alkalmazás a fejlesztői környezetben fut. Ne ossza meg nyilvánosan a részletes kivételadatokat, ha az alkalmazás éles környezetben fut. További információ a környezetek konfigurálásáról: ASP.NET Core futtatókörnyezetek.

A Fejlesztői kivétel lap a következő információkat tartalmazhatja a kivételről és a kérésről:

  • Verem nyomkövetése
  • Lekérdezési sztringparaméterek, ha vannak ilyenek
  • Cookie-k, ha vannak ilyenek
  • Fejlécek
  • Végpont metaadatai, ha vannak ilyenek

A fejlesztői kivételoldal nem garantáltan biztosít semmilyen információt. A teljes hibainformációk naplózása .

Az alábbi képen egy minta fejlesztői kivétellap látható, amelyen animáció látható a lapok és a megjelenített információk megjelenítéséhez:

A fejlesztői kivétellap animáltan jelenik meg az egyes kijelölt lapok megjelenítéséhez.

Egy fejlécet tartalmazó Accept: text/plain kérésre válaszul a Fejlesztői kivételoldal a HTML helyett egyszerű szöveget ad vissza. Például:

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

A Fejlesztői kivétel lap megjelenítése minimális API-ban:

Ez a szakasz a következő mintaalkalmazásra hivatkozik, amely bemutatja a minimális API-k kivételeinek kezelésére vonatkozó módszereket. Kivételt jelez a végpont /exception kérése esetén:

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

Kivételkezelő

Nem fejlesztési környezetekben a Exception Handler Middleware használatával hozzon létre hasznos adatokat.

A hívás konfigurálásához hívja meg a Exception Handler Middlewarekövetkezőt UseExceptionHandler: Az alábbi kód például úgy módosítja az alkalmazást, hogy egy RFC 7807-kompatibilis hasznos adattal válaszoljon az ügyfélnek. További információt a cikk későbbi, Probléma részletei szakaszában talál.

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

Ügyfél- és kiszolgálóhiba-válaszok

Fontolja meg a következő Minimal API-alkalmazást.

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

A /users végpont azt 200 OKjson jelzi User , hogy mikor id nagyobb, mint 0a 400 BAD REQUEST választörzs nélküli állapotkód. A válaszok létrehozásáról további információt a Válaszok létrehozása a Minimal API-alkalmazásokban című témakörben talál.

A Status Code Pages middleware rendszer konfigurálható úgy, hogy az összes HTTP-ügyfélre () vagy kiszolgálóra (400-499500 -599) adott válasz esetén üres törzstartalmat állítsunk elő. A köztes szoftver a UseStatusCodePages bővítmény metódus meghívásával van konfigurálva.

Az alábbi példa például úgy módosítja az alkalmazást, hogy egy RFC 7807-kompatibilis hasznos adattal válaszoljon az ügyfélnek az összes ügyfél- és kiszolgálóválasz esetében, beleértve az útválasztási hibákat (például 404 NOT FOUND). További információkért tekintse meg a Probléma részletei szakaszt .

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

Probléma részletei

A probléma részletei nem az egyetlen válaszformátum a HTTP API-hibák leírásához, azonban gyakran használják őket a HTTP API-k hibáinak jelentésére.

A probléma részletei szolgáltatás implementálja a felületet, amely támogatja a IProblemDetailsService probléma részleteinek létrehozását a ASP.NET Core-ban. A AddProblemDetails(IServiceCollection) bővítménymetódus IServiceCollection regisztrálja az alapértelmezett IProblemDetailsService implementációt.

A ASP.NET Core-alkalmazásokban a következő köztes szoftver generálja a probléma részleteit HTTP-válaszok meghívásakorAddProblemDetails, kivéve, ha a Accept kérelem HTTP-fejléce nem tartalmazza a regisztrált IProblemDetailsWriter (alapértelmezett) által támogatott tartalomtípusokat: application/json

  • ExceptionHandlerMiddleware: Probléma részleteit tartalmazó választ hoz létre, ha nincs definiálva egyéni kezelő.
  • StatusCodePagesMiddleware: Alapértelmezés szerint létrehoz egy probléma részleteit tartalmazó választ.
  • DeveloperExceptionPageMiddleware: Probléma részleteit tartalmazó választ hoz létre a fejlesztés során, ha a kérelem HTTP-fejléce nem tartalmazza Accepta text/html következőt: .

Minimális API-alkalmazások konfigurálhatók úgy, hogy a bővítménymetódus használatával probléma részleteire adott választ generáljanak az összes OLYAN HTTP-ügyfél- és kiszolgálóhiba-válaszhoz, .

Az alábbi kód konfigurálja az alkalmazást a probléma részleteinek létrehozásához:

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

További információ a használatról AddProblemDetails: Probléma részletei

IProblemDetailsService tartalék

A következő kód egy hibát ad vissza, httpContext.Response.WriteAsync("Fallback: An error occurred.") ha a IProblemDetailsService megvalósítás nem tud létrehozni egy 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();

Az előző kód:

  • Hibaüzenetet ír a tartalék kóddal, ha a problemDetailsService rendszer nem tud írni egy ProblemDetails. Például egy végpont, ahol az Elfogadás kérelem fejléce olyan médiatípust határoz meg, amelyet a DefaulProblemDetailsWriter rendszer nem támogat.
  • A Exception Handler Middleware-t használja.

A következő minta az előzőhöz hasonló, azzal a kivételt leszámítva, hogy meghívja a 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);

További hibakezelési funkciók

Migrálás vezérlőkről minimális API-kra

Ha a vezérlőalapú API-król minimális API-kra migrál:

  1. Műveletszűrők cseréje végpontszűrőkre vagy köztes szoftverre
  2. Modellérvényesítés cseréje manuális érvényesítésre vagy egyéni kötésre
  3. Kivételszűrők cseréje a köztes szoftver kivételkezelésére
  4. Probléma részleteinek konfigurálása konzisztens hibaválaszok használatával AddProblemDetails()

Mikor érdemes vezérlőalapú hibakezelést használni?

Szükség esetén fontolja meg a vezérlőalapú API-kat:

  • Összetett modellérvényesítési forgatókönyvek
  • Központosított kivételkezelés több vezérlő között
  • A hibaválasz formázásának részletes szabályozása
  • Integráció MVC-funkciókkal, például szűrőkkel és konvenciókkal

A vezérlőalapú hibakezeléssel kapcsolatos részletes információkért, beleértve az érvényesítési hibákat, a probléma részleteinek testreszabását és a kivételszűrőket, tekintse meg a Vezérlők lap szakaszait.

További erőforrások