Minimum API uygulamalarında hataları işleme

Not

Bu, bu makalenin en son sürümü değildir. Geçerli sürüm için bu makalenin .NET 8 sürümüne bakın.

Önemli

Bu bilgiler, ticari olarak piyasaya sürülmeden önce önemli ölçüde değiştirilebilen bir yayın öncesi ürünle ilgilidir. Burada verilen bilgilerle ilgili olarak Microsoft açık veya zımni hiçbir garanti vermez.

Geçerli sürüm için bu makalenin .NET 8 sürümüne bakın.

David Acker'ın katkılarıyla

Bu makalede, En Düşük API uygulamalarında hataların nasıl işleneceğini açıklanmaktadır.

Özel durumlar

Minimal API uygulamasında, işlenmeyen özel durumları işlemek için iki farklı yerleşik merkezi mekanizma vardır:

Bu bölüm, özel durumları işlemenin yollarını göstermek için aşağıdaki Minimal API uygulamasına başvurur. Uç nokta /exception istendiğinde bir özel durum oluşturur:

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

Geliştirici Özel Durum Sayfası

Geliştirici Özel Durum Sayfası, sunucu hataları için ayrıntılı yığın izlemelerini gösterir. HTTP işlem hattından zaman uyumlu ve zaman uyumsuz özel durumları yakalamak ve hata yanıtları oluşturmak için kullanır DeveloperExceptionPageMiddleware .

ASP.NET Core uygulamaları, her ikisi de aşağıdaki durumlarda varsayılan olarak geliştirici özel durum sayfasını etkinleştirir:

Ara yazılımı yapılandırma hakkında daha fazla bilgi için bkz . Minimal API uygulamalarında ara yazılım.

Yukarıdaki Minimal API uygulamasını kullanarak, işlenmeyen Developer Exception Page bir özel durum algıladığında, aşağıdaki örneğe benzer bir varsayılan düz metin yanıtı oluşturur:

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

Uyarı

Uygulama Geliştirme ortamında çalışmadığı sürece Geliştirici Özel Durum Sayfası'nı etkinleştirmeyin. Uygulama üretimde çalışırken ayrıntılı özel durum bilgilerini herkese açık olarak paylaşmayın. Ortamları yapılandırma hakkında daha fazla bilgi için bkz . ASP.NET Core'da birden çok ortam kullanma.

Özel durum işleyicisi

Geliştirme dışı ortamlarda hata yükü oluşturmak için Özel Durum İşleyici ara yazılımını kullanın. öğesini yapılandırmak için öğesini çağırınException Handler MiddlewareUseExceptionHandler.

Örneğin, aşağıdaki kod uygulamayı istemciye RFC 7807 uyumlu bir yükle yanıt verecek şekilde değiştirir. Daha fazla bilgi için Sorun Ayrıntıları bölümüne bakın.

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

İstemci ve Sunucu hata yanıtları

Aşağıdaki Minimal API uygulamasını göz önünde bulundurun.

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

/users nokta json200 OK, ne zaman id değerinin değerinden 0User büyük olduğunu gösterir, aksi takdirde yanıt gövdesi olmayan bir 400 BAD REQUEST durum kodu oluşturur. Yanıt oluşturma hakkında daha fazla bilgi için bkz . Minimal API uygulamalarında yanıt oluşturma.

Status Code Pages middleware, tüm HTTP istemcisi () veya sunucu (500599- -400499) yanıtları için boş olduğunda ortak bir gövde içeriği üretecek şekilde yapılandırılabilir. Ara yazılım UseStatusCodePages uzantı yöntemi çağrılarak yapılandırılır.

Örneğin, aşağıdaki örnek uygulamayı yönlendirme hataları (örneğin, 404 NOT FOUND) dahil olmak üzere tüm istemci ve sunucu yanıtları için istemciye RFC 7807 uyumlu bir yükle yanıt verecek şekilde değiştirir. Daha fazla bilgi için Sorun Ayrıntıları bölümüne bakın.

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

Sorun ayrıntıları

Sorun Ayrıntıları , HTTP API hatasını açıklayan tek yanıt biçimi değildir, ancak genellikle HTTP API'lerine yönelik hataları bildirmek için kullanılır.

Sorun ayrıntıları hizmeti, ASP.NET Core'da sorun ayrıntıları oluşturmayı destekleyen arabirimini uygular IProblemDetailsService . AddProblemDetails üzerindeki IServiceCollection uzantı yöntemi, varsayılan IProblemDetailsService uygulamayı kaydeder.

ASP.NET Core uygulamalarında, istek HTTP üst bilgisinin kayıtlı tarafından desteklenen içerik türlerinden birini içermemesiAcceptdışında, aşağıdaki ara yazılım çağrıldığında AddProblemDetails sorun ayrıntıları HTTP yanıtları oluşturur (varsayılan: application/json):IProblemDetailsWriter

Uzantı yöntemi kullanılarak AddProblemDetails henüz gövde içeriği olmayan tüm HTTP istemci ve sunucu hata yanıtları için sorun ayrıntıları yanıtı oluşturmak üzere en az API uygulamaları yapılandırılabilir.

Aşağıdaki kod, uygulamayı sorun ayrıntıları oluşturacak şekilde yapılandırıyor:

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

kullanma AddProblemDetailshakkında daha fazla bilgi için bkz. Sorun Ayrıntıları

IProblemDetailsService geri dönüşü

Aşağıdaki kodda, httpContext.Response.WriteAsync("Fallback: An error occurred.") uygulama bir oluşturamıyorsa IProblemDetailsService bir ProblemDetailshata döndürür:

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

Yukarıdaki kod:

  • bir yazamıyorsa problemDetailsService geri dönüş koduyla bir ProblemDetailshata iletisi yazar. Örneğin, Accept isteği üst bilgisinin desteklemediği bir medya türü DefaulProblemDetailsWriter belirttiği bir uç nokta.
  • Özel Durum İşleyici ara yazılımını kullanır.

Aşağıdaki örnek, öğesini çağırması dışında öncekine Status Code Pages middlewarebenzer.

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

Bu makalede, En Düşük API uygulamalarında hataların nasıl işleneceğini açıklanmaktadır.

Özel durumlar

Minimal API uygulamasında, işlenmeyen özel durumları işlemek için iki farklı yerleşik merkezi mekanizma vardır:

Bu bölüm, özel durumları işlemenin yollarını göstermek için aşağıdaki Minimal API uygulamasına başvurur. Uç nokta /exception istendiğinde bir özel durum oluşturur:

var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();

app.Map("/exception", () 
    => { throw new InvalidOperationException("Sample Exception"); });

app.Run();

Geliştirici Özel Durum Sayfası

Geliştirici Özel Durum Sayfası, sunucu hataları için ayrıntılı yığın izlemelerini gösterir. HTTP işlem hattından zaman uyumlu ve zaman uyumsuz özel durumları yakalamak ve hata yanıtları oluşturmak için kullanır DeveloperExceptionPageMiddleware .

ASP.NET Core uygulamaları, her ikisi de aşağıdaki durumlarda varsayılan olarak geliştirici özel durum sayfasını etkinleştirir:

Ara yazılımı yapılandırma hakkında daha fazla bilgi için bkz . Minimal API uygulamalarında ara yazılım.

Yukarıdaki Minimal API uygulamasını kullanarak, işlenmeyen Developer Exception Page bir özel durum algıladığında, aşağıdaki örneğe benzer bir varsayılan düz metin yanıtı oluşturur:

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

Uyarı

Uygulama Geliştirme ortamında çalışmadığı sürece Geliştirici Özel Durum Sayfası'nı etkinleştirmeyin. Uygulama üretimde çalışırken ayrıntılı özel durum bilgilerini herkese açık olarak paylaşmayın. Ortamları yapılandırma hakkında daha fazla bilgi için bkz . ASP.NET Core'da birden çok ortam kullanma.

Özel durum işleyicisi

Geliştirme dışı ortamlarda hata yükü oluşturmak için Özel Durum İşleyici ara yazılımını kullanın. öğesini yapılandırmak için öğesini çağırınException Handler MiddlewareUseExceptionHandler.

Örneğin, aşağıdaki kod uygulamayı istemciye RFC 7807 uyumlu bir yükle yanıt verecek şekilde değiştirir. Daha fazla bilgi için Sorun Ayrıntıları bölümüne bakın.

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

İstemci ve Sunucu hata yanıtları

Aşağıdaki Minimal API uygulamasını göz önünde bulundurun.

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

/users nokta json200 OK, ne zaman id değerinin değerinden 0User büyük olduğunu gösterir, aksi takdirde yanıt gövdesi olmayan bir 400 BAD REQUEST durum kodu oluşturur. Yanıt oluşturma hakkında daha fazla bilgi için bkz . Minimal API uygulamalarında yanıt oluşturma.

Status Code Pages middleware, tüm HTTP istemcisi () veya sunucu (500599- -400499) yanıtları için boş olduğunda ortak bir gövde içeriği üretecek şekilde yapılandırılabilir. Ara yazılım UseStatusCodePages uzantı yöntemi çağrılarak yapılandırılır.

Örneğin, aşağıdaki örnek uygulamayı yönlendirme hataları (örneğin, 404 NOT FOUND) dahil olmak üzere tüm istemci ve sunucu yanıtları için istemciye RFC 7807 uyumlu bir yükle yanıt verecek şekilde değiştirir. Daha fazla bilgi için Sorun Ayrıntıları bölümüne bakın.

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

Sorun ayrıntıları

Sorun Ayrıntıları , HTTP API hatasını açıklayan tek yanıt biçimi değildir, ancak genellikle HTTP API'lerine yönelik hataları bildirmek için kullanılır.

Sorun ayrıntıları hizmeti, ASP.NET Core'da sorun ayrıntıları oluşturmayı destekleyen arabirimini uygular IProblemDetailsService . AddProblemDetails üzerindeki IServiceCollection uzantı yöntemi, varsayılan IProblemDetailsService uygulamayı kaydeder.

ASP.NET Core uygulamalarında, istek HTTP üst bilgisinin kayıtlı tarafından desteklenen içerik türlerinden birini içermemesiAcceptdışında, aşağıdaki ara yazılım çağrıldığında AddProblemDetails sorun ayrıntıları HTTP yanıtları oluşturur (varsayılan: application/json):IProblemDetailsWriter

Uzantı yöntemi kullanılarak AddProblemDetails henüz gövde içeriği olmayan tüm HTTP istemci ve sunucu hata yanıtları için sorun ayrıntıları yanıtı oluşturmak üzere en az API uygulamaları yapılandırılabilir.

Aşağıdaki kod, uygulamayı sorun ayrıntıları oluşturacak şekilde yapılandırıyor:

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

kullanma AddProblemDetailshakkında daha fazla bilgi için bkz. Sorun Ayrıntıları