ASP.NET Core hatalarını işleme
Uyarı
ASP.NET Core'un bu sürümü artık desteklenmiyor. Daha fazla bilgi için bkz . .NET ve .NET Core Destek İlkesi. Geçerli sürüm için bu makalenin .NET 8 sürümüne bakın.
Tarafından Tom Dykstra
Bu makalede, ASP.NET Core web uygulamalarında hataları işlemeye yönelik yaygın yaklaşımlar ele alınıyor. Ayrıca bkz. ASP.NET Core denetleyici tabanlı web API'lerindeki hataları işleme ve Minimum API'lerdeki hataları işleme.
Blazor Bu makaledeki yönergeleri ekleyen veya yerine geçen hata işleme kılavuzu için bkz. ASP.NET Core Blazor uygulamalarında hataları işleme.
Geliştirici özel durum sayfası
Geliştirici Özel Durum Sayfası, işlenmeyen istek özel durumları hakkında ayrıntılı bilgiler görüntüler. HTTP işlem hattından zaman uyumlu ve zaman uyumsuz özel durumları yakalamak ve hata yanıtları oluşturmak için kullanır DeveloperExceptionPageMiddleware . Geliştirici özel durum sayfası ara yazılım işlem hattında erken çalıştırılır, böylece izleyen ara yazılımda işlenmeyen özel durumları yakalayabilir.
ASP.NET Core uygulamaları, her ikisi de aşağıdaki durumlarda varsayılan olarak geliştirici özel durum sayfasını etkinleştirir:
- Geliştirme ortamında çalıştırılıyor.
- Uygulama, geçerli şablonlarla, yani kullanılarak WebApplication.CreateBuilderoluşturulmuştur.
Önceki şablonlar kullanılarak, yani kullanılarak WebHost.CreateDefaultBuilderoluşturulan uygulamalar, öğesini çağırarak app.UseDeveloperExceptionPage
geliştirici özel durum sayfasını etkinleştirebilir.
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.
Geliştirici Özel Durum Sayfası, özel durum ve istek hakkında aşağıdaki bilgileri içerebilir:
- Yığın izleme
- Varsa sorgu dizesi parametreleri
- Varsa tanımlama bilgileri
- Üst Bilgiler
- Varsa uç nokta meta verileri
Geliştirici Özel Durum Sayfası'nın herhangi bir bilgi sağlaması garanti değildir. Tam hata bilgileri için Günlüğe Kaydetme özelliğini kullanın.
Aşağıdaki görüntüde, sekmeleri ve görüntülenen bilgileri gösteren animasyon içeren örnek bir geliştirici özel durum sayfası gösterilmektedir:
Üst bilgi içeren bir Accept: text/plain
isteğe yanıt olarak, Geliştirici Özel Durum Sayfası HTML yerine düz metin döndürür. Örneğin:
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
Özel durum işleyici sayfası
Üretim ortamı için özel bir hata işleme sayfası yapılandırmak için öğesini çağırınUseExceptionHandler. Ara yazılımı işleyen bu özel durum:
- İşlenmeyen özel durumları yakalar ve günlüğe kaydeder.
- Belirtilen yolu kullanarak isteği alternatif bir işlem hattında yeniden yürütür. Yanıt başlatıldıysa istek yeniden yürütülemez. Şablon tarafından oluşturulan kod, yolu kullanarak isteği yeniden yürütür
/Error
.
Uyarı
Alternatif işlem hattı kendi özel durumu oluşturursa, Özel Durum İşleme Ara Yazılımı özgün özel durumu yeniden oluşturur.
Bu ara yazılım istek işlem hattını yeniden yürütebileceğinden:
- Ara yazılımların yeniden giriş işlemini aynı istekle işlemesi gerekir. Bu normalde, çağrısından
_next
sonra durumlarını temizleme veya işlemi yeniden yapmaktan kaçınmak için üzerindeki işlemleriniHttpContext
önbelleğe alma anlamına gelir. İstek gövdesiyle ilgilenirken bu, Sonuçları Form okuyucusu gibi arabelleğe alma veya önbelleğe alma anlamına gelir. - UseExceptionHandler(IApplicationBuilder, String) Şablonlarda kullanılan aşırı yükleme için yalnızca istek yolu değiştirilir ve yol verileri temizlenir. Üst bilgiler, yöntem ve öğeler gibi istek verilerinin tümü olduğu gibi yeniden kullanılır.
- Kapsamı belirlenmiş hizmetler aynı kalır.
Aşağıdaki örnekte, UseExceptionHandler Geliştirme dışı ortamlarda özel durum işleme ara yazılımını ekler:
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
Sayfalar uygulama şablonu, Razor Sayfalar klasöründe bir Hata sayfası (.cshtml
) ve PageModel sınıf (ErrorModel
) sağlar. Bir MVC uygulaması için proje şablonu, denetleyici için Home bir Error
eylem yöntemi ve Hata görünümü içerir.
Özel durum işleme ara yazılımı özgün HTTP yöntemini kullanarak isteği yeniden yürütür. Hata işleyicisi uç noktası belirli bir HTTP yöntemleri kümesiyle sınırlıysa, yalnızca bu HTTP yöntemleri için çalışır. Örneğin, özniteliğini kullanan [HttpGet]
bir MVC denetleyicisi eylemi yalnızca GET istekleri için çalıştırılır. Tüm isteklerin özel hata işleme sayfasına ulaştığından emin olmak için bunları belirli bir HTTP yöntemleri kümesiyle kısıtlamayın.
Özel durumları özgün HTTP yöntemine göre farklı şekilde işlemek için:
- Sayfalar için Razor birden çok işleyici yöntemi oluşturun. Örneğin, GET özel durumlarını işlemek için kullanın
OnGet
ve POST özel durumlarını işlemek için kullanınOnPost
. - MVC için, birden çok eyleme HTTP fiili öznitelikleri uygulayın. Örneğin, GET özel durumlarını işlemek için kullanın
[HttpGet]
ve POST özel durumlarını işlemek için kullanın[HttpPost]
.
Kimliği doğrulanmamış kullanıcıların özel hata işleme sayfasını görüntülemesine izin vermek için anonim erişimi desteklediğinden emin olun.
Özel duruma erişme
Hata işleyicisinde özel duruma ve özgün istek yoluna erişmek için kullanın IExceptionHandlerPathFeature . Aşağıdaki örnek, oluşturulan özel durum hakkında daha fazla bilgi almak için kullanır IExceptionHandlerPathFeature
:
[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
[IgnoreAntiforgeryToken]
public class ErrorModel : PageModel
{
public string? RequestId { get; set; }
public bool ShowRequestId => !string.IsNullOrEmpty(RequestId);
public string? ExceptionMessage { get; set; }
public void OnGet()
{
RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier;
var exceptionHandlerPathFeature =
HttpContext.Features.Get<IExceptionHandlerPathFeature>();
if (exceptionHandlerPathFeature?.Error is FileNotFoundException)
{
ExceptionMessage = "The file was not found.";
}
if (exceptionHandlerPathFeature?.Path == "/")
{
ExceptionMessage ??= string.Empty;
ExceptionMessage += " Page: Home.";
}
}
}
Uyarı
Hassas hata bilgilerini istemcilere sunma. Hata sunma bir güvenlik riskidir.
Özel durum işleyici lambda
Özel özel durum işleyici sayfasının alternatifi, öğesine UseExceptionHandlerbir lambda sağlamaktır. Lambda kullanmak, yanıtı döndürmeden önce hataya erişim sağlar.
Aşağıdaki kod özel durum işleme için bir lambda kullanır:
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler(exceptionHandlerApp =>
{
exceptionHandlerApp.Run(async context =>
{
context.Response.StatusCode = StatusCodes.Status500InternalServerError;
// using static System.Net.Mime.MediaTypeNames;
context.Response.ContentType = Text.Plain;
await context.Response.WriteAsync("An exception was thrown.");
var exceptionHandlerPathFeature =
context.Features.Get<IExceptionHandlerPathFeature>();
if (exceptionHandlerPathFeature?.Error is FileNotFoundException)
{
await context.Response.WriteAsync(" The file was not found.");
}
if (exceptionHandlerPathFeature?.Path == "/")
{
await context.Response.WriteAsync(" Page: Home.");
}
});
});
app.UseHsts();
}
Lambda kullanmanın bir diğer yolu da aşağıdaki örnekte olduğu gibi durum kodunu özel durum türüne göre ayarlamaktır:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddProblemDetails();
var app = builder.Build();
if (app.Environment.IsDevelopment())
{
app.UseExceptionHandler(new ExceptionHandlerOptions
{
StatusCodeSelector = ex => ex is TimeoutException
? StatusCodes.Status503ServiceUnavailable
: StatusCodes.Status500InternalServerError
});
}
Uyarı
Hassas hata bilgilerini istemcilere sunma. Hata sunma bir güvenlik riskidir.
IExceptionHandler
IExceptionHandler , geliştiriciye merkezi bir konumda bilinen özel durumları işlemek için geri çağırma sağlayan bir arabirimdir.
IExceptionHandler
uygulamaları çağrılarak IServiceCollection.AddExceptionHandler<T>
kaydedilir. Bir IExceptionHandler
örneğin ömrü tekildir. Birden çok uygulama eklenebilir ve bunlar kayıtlı sırayla çağrılır.
Bir özel durum işleyicisi bir isteği işlerse, işlemeyi durdurmak için geri dönebilir true
. Bir özel durum işleyicisi herhangi bir özel durum işleyicisi tarafından işlenmezse denetim, ara yazılımdaki varsayılan davranışa ve seçeneklere geri döner. İşlenen ve işlenmeyen özel durumlar için farklı ölçümler ve günlükler yayılır.
Aşağıdaki örnekte bir IExceptionHandler
uygulama gösterilmektedir:
using Microsoft.AspNetCore.Diagnostics;
namespace ErrorHandlingSample
{
public class CustomExceptionHandler : IExceptionHandler
{
private readonly ILogger<CustomExceptionHandler> logger;
public CustomExceptionHandler(ILogger<CustomExceptionHandler> logger)
{
this.logger = logger;
}
public ValueTask<bool> TryHandleAsync(
HttpContext httpContext,
Exception exception,
CancellationToken cancellationToken)
{
var exceptionMessage = exception.Message;
logger.LogError(
"Error Message: {exceptionMessage}, Time of occurrence {time}",
exceptionMessage, DateTime.UtcNow);
// Return false to continue with the default behavior
// - or - return true to signal that this exception is handled
return ValueTask.FromResult(false);
}
}
}
Aşağıdaki örnekte, bağımlılık ekleme için bir IExceptionHandler
uygulamanın nasıl kaydedilecekleri gösterilmektedir:
using ErrorHandlingSample;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddDatabaseDeveloperPageExceptionFilter();
builder.Services.AddRazorPages();
builder.Services.AddExceptionHandler<CustomExceptionHandler>();
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
// Remaining Program.cs code omitted for brevity
Yukarıdaki kod Geliştirme ortamında çalıştırıldığında:
CustomExceptionHandler
bir özel durumu işlemek için ilk olarak çağrılır.- Özel durumu günlüğe kaydettikten sonra yöntemi döndürür
false
,TryHandleAsync
bu nedenle geliştirici özel durum sayfası gösterilir.
Diğer ortamlarda:
CustomExceptionHandler
bir özel durumu işlemek için ilk olarak çağrılır.- Özel durumu
TryHandleAsync
günlüğe kaydettikten sonra yöntemi döndürürfalse
, böylece/Error
sayfa gösterilir.
UseStatusCodePages
Varsayılan olarak, ASP.NET Core uygulaması HTTP hata durum kodları için 404 - Bulunamadı gibi bir durum kodu sayfası sağlamaz. Uygulama gövdesi olmayan bir HTTP 400-599 hata durum kodu ayarladığında, durum kodunu ve boş bir yanıt gövdesini döndürür. Yaygın hata durum kodları için varsayılan yalnızca metin işleyicilerini etkinleştirmek için çağrısında UseStatusCodePages kullanın Program.cs
:
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseStatusCodePages();
İstek işleme ara yazılımından önce çağırın UseStatusCodePages
. Örneğin, Statik Dosya Ara Yazılımı ve Uç Noktalar Ara Yazılımı'nın önünde çağırın UseStatusCodePages
.
Kullanılmadığında UseStatusCodePages
, uç nokta olmadan URL'ye gitmek, uç noktanın bulunamadığını belirten tarayıcıya bağlı bir hata iletisi döndürür. Çağrıldığında UseStatusCodePages
, tarayıcı aşağıdaki yanıtı döndürür:
Status Code: 404; Not Found
UseStatusCodePages
genellikle üretimde kullanılmaz çünkü kullanıcılar için yararlı olmayan bir ileti döndürür.
Not
Durum kodu sayfaları ara yazılımı özel durumları yakalamaz. Özel hata işleme sayfası sağlamak için özel durum işleyici sayfasını kullanın.
Biçim dizesi ile UseStatusCodePages
Yanıt içerik türünü ve metnini özelleştirmek için, bir içerik türü ve biçim dizesi alan öğesinin aşırı yüklemesini UseStatusCodePages kullanın:
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
// using static System.Net.Mime.MediaTypeNames;
app.UseStatusCodePages(Text.Plain, "Status Code Page: {0}");
Yukarıdaki kodda, {0}
hata kodu için bir yer tutucudur.
UseStatusCodePages
kullanıcılar için yararlı olmayan bir ileti döndürdüğü için, biçim dizesi genellikle üretimde kullanılmaz.
Lambda ile UseStatusCodePages
Özel hata işleme ve yanıt yazma kodu belirtmek için bir lambda ifadesi alan öğesinin aşırı yüklemesini UseStatusCodePages kullanın:
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseStatusCodePages(async statusCodeContext =>
{
// using static System.Net.Mime.MediaTypeNames;
statusCodeContext.HttpContext.Response.ContentType = Text.Plain;
await statusCodeContext.HttpContext.Response.WriteAsync(
$"Status Code Page: {statusCodeContext.HttpContext.Response.StatusCode}");
});
UseStatusCodePages
lambda ile genellikle üretimde kullanılmaz çünkü kullanıcılar için yararlı olmayan bir ileti döndürür.
UseStatusCodePagesWithRedirects
UseStatusCodePagesWithRedirects Uzantı yöntemi:
- İstemciye bir 302 - Bulundu durum kodu gönderir.
- İstemciyi URL şablonunda sağlanan hata işleme uç noktasına yönlendirir. Hata işleme uç noktası genellikle hata bilgilerini görüntüler ve HTTP 200 döndürür.
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseStatusCodePagesWithRedirects("/StatusCode/{0}");
URL şablonu, önceki kodda gösterildiği gibi durum kodu için bir {0}
yer tutucu içerebilir. URL şablonu (tilde) ile ~
başlıyorsa, ~
yerine uygulamanın PathBase
olur. Uygulamada bir uç nokta belirtirken, uç nokta için bir MVC görünümü veya Razor sayfası oluşturun.
Bu yöntem genellikle uygulama şu durumlarda kullanılır:
- genellikle farklı bir uygulamanın hatayı işlediği durumlarda istemciyi farklı bir uç noktaya yönlendirmelidir. Web uygulamaları için istemcinin tarayıcı adres çubuğu yeniden yönlendirilen uç noktayı yansıtır.
- İlk yeniden yönlendirme yanıtıyla özgün durum kodunu korumamalı ve döndürmemelidir.
UseStatusCodePagesWithReExecute
UseStatusCodePagesWithReExecute Uzantı yöntemi:
- Alternatif bir yol kullanarak istek işlem hattını yeniden yürüterek yanıt gövdesini oluşturur.
- İşlem hattı yeniden yürütülmeden önce veya sonra durum kodunu değiştirmez.
Yeni işlem hattı, durum kodu üzerinde tam denetime sahip olduğundan yeni işlem hattı yürütmesi yanıtın durum kodunu değiştirebilir. Yeni işlem hattı durum kodunu değiştirmezse, özgün durum kodu istemciye gönderilir.
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseStatusCodePagesWithReExecute("/StatusCode/{0}");
Uygulama içinde bir uç nokta belirtilirse, uç nokta için bir MVC görünümü veya Razor sayfası oluşturun.
Bu yöntem genellikle uygulamanın aşağıdakileri yapması gerektiğinde kullanılır:
- İsteği farklı bir uç noktaya yeniden yönlendirmeden işleyin. Web uygulamaları için istemcinin tarayıcı adres çubuğu başlangıçta istenen uç noktayı yansıtır.
- Yanıtla birlikte özgün durum kodunu koruyun ve döndürin.
URL şablonu ile /
başlamalıdır ve durum kodu için bir yer tutucu {0}
içerebilir. Durum kodunu sorgu dizesi parametresi olarak geçirmek için içine ikinci bir bağımsız değişken UseStatusCodePagesWithReExecute
geçirin. Örneğin:
var app = builder.Build();
app.UseStatusCodePagesWithReExecute("/StatusCode", "?statusCode={0}");
Hatayı işleyen uç nokta, aşağıdaki örnekte gösterildiği gibi hatayı oluşturan özgün URL'yi alabilir:
[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
public class StatusCodeModel : PageModel
{
public int OriginalStatusCode { get; set; }
public string? OriginalPathAndQuery { get; set; }
public void OnGet(int statusCode)
{
OriginalStatusCode = statusCode;
var statusCodeReExecuteFeature =
HttpContext.Features.Get<IStatusCodeReExecuteFeature>();
if (statusCodeReExecuteFeature is not null)
{
OriginalPathAndQuery = $"{statusCodeReExecuteFeature.OriginalPathBase}"
+ $"{statusCodeReExecuteFeature.OriginalPath}"
+ $"{statusCodeReExecuteFeature.OriginalQueryString}";
}
}
}
Bu ara yazılım istek işlem hattını yeniden yürütebileceğinden:
- Ara yazılımların yeniden giriş işlemini aynı istekle işlemesi gerekir. Bu normalde, çağrısından
_next
sonra durumlarını temizleme veya işlemi yeniden yapmaktan kaçınmak için üzerindeki işlemleriniHttpContext
önbelleğe alma anlamına gelir. İstek gövdesiyle ilgilenirken bu, Sonuçları Form okuyucusu gibi arabelleğe alma veya önbelleğe alma anlamına gelir. - Kapsamı belirlenmiş hizmetler aynı kalır.
Durum kodu sayfalarını devre dışı bırakma
MVC denetleyicisinin veya eylem yönteminin durum kodu sayfalarını devre dışı bırakmak için [SkipStatusCodePages] özniteliğini kullanın.
Pages işleyici yönteminde veya MVC denetleyicisinde Razor belirli istekler için durum kodu sayfalarını devre dışı bırakmak için kullanın IStatusCodePagesFeature:
public void OnGet()
{
var statusCodePagesFeature =
HttpContext.Features.Get<IStatusCodePagesFeature>();
if (statusCodePagesFeature is not null)
{
statusCodePagesFeature.Enabled = false;
}
}
Özel durum işleme kodu
Özel durum işleme sayfalarındaki kod da özel durumlar oluşturabilir. Üretim hata sayfaları kapsamlı bir şekilde test edilmeli ve kendi özel durumlarının oluşmasını önlemek için ek özen gösterilmelidir.
Yanıt üst bilgileri
Yanıtın üst bilgileri gönderildikten sonra:
- Uygulama yanıtın durum kodunu değiştiremez.
- Özel durum sayfaları veya işleyicileri çalıştırılamaz. Yanıt tamamlanmalıdır veya bağlantı durdurulmalıdır.
Sunucu özel durum işleme
Bir uygulamadaki özel durum işleme mantığına ek olarak, HTTP sunucusu uygulaması bazı özel durumları işleyebilir. Sunucu yanıt üst bilgileri gönderilmeden önce bir özel durum yakalarsa, yanıt gövdesi olmadan bir 500 - Internal Server Error
yanıt gönderir. Yanıt üst bilgileri gönderildikten sonra sunucu bir özel durum yakalarsa, sunucu bağlantıyı kapatır. Uygulama tarafından işlenmemiş istekler sunucu tarafından işlenir. Sunucu isteği işlerken oluşan özel durumlar, sunucunun özel durum işlemesi tarafından işlenir. Uygulamanın özel hata sayfaları, özel durum işleme ara yazılımı ve filtreler bu davranışı etkilemez.
Özel durum işlemeyi başlatma
Yalnızca barındırma katmanı, uygulama başlatma sırasında gerçekleşen özel durumları işleyebilir. Konak, başlangıç hatalarını yakalamak ve ayrıntılı hataları yakalamak için yapılandırılabilir.
Barındırma katmanı, yakalanan başlatma hatası için yalnızca ana bilgisayar adresi/bağlantı noktası bağlaması sonrasında hata oluşması durumunda bir hata sayfası gösterebilir. Bağlama başarısız olursa:
- Barındırma katmanı kritik bir özel durumu günlüğe kaydeder.
- dotnet işlemi kilitleniyor.
- HTTP sunucusu olduğunda hiçbir hata sayfası görüntülenmez Kestrel.
IIS (veya Azure Uygulaması Hizmeti) veya IIS Express üzerinde çalışırken, işlem başlatılamıyorsa ASP.NET Çekirdek Modülü tarafından 502.5 - İşlem Hatası döndürülür. Daha fazla bilgi için bkz. Azure Uygulaması Hizmeti ve IIS'de ASP.NET Core sorunlarını giderme.
Veritabanı hata sayfası
Veritabanı geliştirici sayfası özel durum filtresi AddDatabaseDeveloperPageExceptionFilter , Entity Framework Core geçişleri kullanılarak çözümlenebilen veritabanıyla ilgili özel durumları yakalar. Bu özel durumlar oluştuğunda, sorunu çözmek için olası eylemlerin ayrıntılarıyla birlikte bir HTML yanıtı oluşturulur. Bu sayfa yalnızca Geliştirme ortamında etkinleştirilir. Aşağıdaki kod, Veritabanı geliştirici sayfası özel durum filtresini ekler:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddDatabaseDeveloperPageExceptionFilter();
builder.Services.AddRazorPages();
Özel durum filtreleri
MVC uygulamalarında özel durum filtreleri genel olarak veya denetleyici başına veya eylem temelinde yapılandırılabilir. Razor Sayfalar uygulamalarında, bunlar genel olarak veya sayfa modeli başına yapılandırılabilir. Bu filtreler, bir denetleyici eyleminin veya başka bir filtrenin yürütülmesi sırasında oluşan işlenmeyen özel durumları işler. Daha fazla bilgi için bkz . ASP.NET Core'daki filtreler.
Özel durum filtreleri, MVC eylemleri içinde oluşan özel durumları yakalamak için kullanışlıdır, ancak yerleşik özel durum işleme ara yazılımıUseExceptionHandler kadar esnek değildir. Hangi MVC eyleminin seçildiğine göre farklı hata işleme gerçekleştirmeniz gerekmediği sürece kullanmanızı UseExceptionHandler
öneririz.
Model durumu hataları
Model durumu hatalarını işleme hakkında bilgi için bkz . Model bağlama ve Model doğrulama.
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(IServiceCollection) ü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çermemesiAccept
dışı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
- ExceptionHandlerMiddleware: Özel işleyici tanımlanmadığında bir sorun ayrıntıları yanıtı oluşturur.
- StatusCodePagesMiddleware: Varsayılan olarak bir sorun ayrıntıları yanıtı oluşturur.
- DeveloperExceptionPageMiddleware: İstek HTTP üst bilgisi içermediğinde
Accept
text/html
geliştirme aşamasında bir sorun ayrıntıları yanıtı oluşturur.
Aşağıdaki kod, uygulamayı henüz gövde içeriği olmayan tüm HTTP istemcisi ve sunucu hata yanıtları için bir sorun ayrıntıları yanıtı oluşturacak şekilde yapılandırır:
builder.Services.AddProblemDetails();
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler();
app.UseHsts();
}
app.UseStatusCodePages();
Sonraki bölümde sorun ayrıntıları yanıt gövdesinin nasıl özelleştirileceği gösterilmektedir.
Sorun ayrıntılarını özelleştirme
öğesinin ProblemDetails
otomatik olarak oluşturulması, aşağıdaki seçeneklerden herhangi biri kullanılarak özelleştirilebilir:
ProblemDetailsOptions.CustomizeProblemDetails
komutunu kullanma- Özel kullanım
IProblemDetailsWriter
- ara yazılımda öğesini
IProblemDetailsService
çağırma
CustomizeProblemDetails
işlem
Oluşturulan sorun ayrıntıları kullanılarak CustomizeProblemDetailsözelleştirilebilir ve özelleştirmeler otomatik olarak oluşturulan tüm sorun ayrıntılarına uygulanır.
Ayarlamak için CustomizeProblemDetailsaşağıdaki kod kullanılırProblemDetailsOptions:
builder.Services.AddProblemDetails(options =>
options.CustomizeProblemDetails = ctx =>
ctx.ProblemDetails.Extensions.Add("nodeId", Environment.MachineName));
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler();
app.UseHsts();
}
app.UseStatusCodePages();
Örneğin, bir HTTP Status 400 Bad Request
uç nokta sonucu aşağıdaki sorun ayrıntıları yanıt gövdesini oluşturur:
{
"type": "https://tools.ietf.org/html/rfc9110#section-15.5.1",
"title": "Bad Request",
"status": 400,
"nodeId": "my-machine-name"
}
Töre IProblemDetailsWriter
Gelişmiş özelleştirmeler için bir IProblemDetailsWriter uygulama oluşturulabilir.
public class SampleProblemDetailsWriter : IProblemDetailsWriter
{
// Indicates that only responses with StatusCode == 400
// are handled by this writer. All others are
// handled by different registered writers if available.
public bool CanWrite(ProblemDetailsContext context)
=> context.HttpContext.Response.StatusCode == 400;
public ValueTask WriteAsync(ProblemDetailsContext context)
{
// Additional customizations.
// Write to the response.
var response = context.HttpContext.Response;
return new ValueTask(response.WriteAsJsonAsync(context.ProblemDetails));
}
}
Not: Özel IProblemDetailsWriter
kullanılırken, özel IProblemDetailsWriter
öğesinin , , AddControllersWithViewsAddControllersveya AddMvcçağrılmadan AddRazorPagesönce kaydedilmesi gerekir:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddTransient<IProblemDetailsWriter, SampleProblemDetailsWriter>();
var app = builder.Build();
// Middleware to handle writing problem details to the response.
app.Use(async (context, next) =>
{
await next(context);
var mathErrorFeature = context.Features.Get<MathErrorFeature>();
if (mathErrorFeature is not null)
{
if (context.RequestServices.GetService<IProblemDetailsWriter>() is
{ } problemDetailsService)
{
if (problemDetailsService.CanWrite(new ProblemDetailsContext() { HttpContext = context }))
{
(string Detail, string Type) details = mathErrorFeature.MathError switch
{
MathErrorType.DivisionByZeroError => ("Divison by zero is not defined.",
"https://en.wikipedia.org/wiki/Division_by_zero"),
_ => ("Negative or complex numbers are not valid input.",
"https://en.wikipedia.org/wiki/Square_root")
};
await problemDetailsService.WriteAsync(new ProblemDetailsContext
{
HttpContext = context,
ProblemDetails =
{
Title = "Bad Input",
Detail = details.Detail,
Type = details.Type
}
});
}
}
}
});
// /divide?numerator=2&denominator=4
app.MapGet("/divide", (HttpContext context, double numerator, double denominator) =>
{
if (denominator == 0)
{
var errorType = new MathErrorFeature
{
MathError = MathErrorType.DivisionByZeroError
};
context.Features.Set(errorType);
return Results.BadRequest();
}
return Results.Ok(numerator / denominator);
});
// /squareroot?radicand=16
app.MapGet("/squareroot", (HttpContext context, double radicand) =>
{
if (radicand < 0)
{
var errorType = new MathErrorFeature
{
MathError = MathErrorType.NegativeRadicandError
};
context.Features.Set(errorType);
return Results.BadRequest();
}
return Results.Ok(Math.Sqrt(radicand));
});
app.Run();
Ara Yazılımdan sorun ayrıntıları
ile CustomizeProblemDetails kullanmak ProblemDetailsOptions için alternatif bir yaklaşım, ara yazılımı ayarlamaktırProblemDetails. Bir sorun ayrıntıları yanıtı çağrılarak IProblemDetailsService.WriteAsync
yazılabilir:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllers();
builder.Services.AddProblemDetails();
var app = builder.Build();
app.UseHttpsRedirection();
app.UseStatusCodePages();
// Middleware to handle writing problem details to the response.
app.Use(async (context, next) =>
{
await next(context);
var mathErrorFeature = context.Features.Get<MathErrorFeature>();
if (mathErrorFeature is not null)
{
if (context.RequestServices.GetService<IProblemDetailsService>() is
{ } problemDetailsService)
{
(string Detail, string Type) details = mathErrorFeature.MathError switch
{
MathErrorType.DivisionByZeroError => ("Divison by zero is not defined.",
"https://en.wikipedia.org/wiki/Division_by_zero"),
_ => ("Negative or complex numbers are not valid input.",
"https://en.wikipedia.org/wiki/Square_root")
};
await problemDetailsService.WriteAsync(new ProblemDetailsContext
{
HttpContext = context,
ProblemDetails =
{
Title = "Bad Input",
Detail = details.Detail,
Type = details.Type
}
});
}
}
});
// /divide?numerator=2&denominator=4
app.MapGet("/divide", (HttpContext context, double numerator, double denominator) =>
{
if (denominator == 0)
{
var errorType = new MathErrorFeature { MathError =
MathErrorType.DivisionByZeroError };
context.Features.Set(errorType);
return Results.BadRequest();
}
return Results.Ok(numerator / denominator);
});
// /squareroot?radicand=16
app.MapGet("/squareroot", (HttpContext context, double radicand) =>
{
if (radicand < 0)
{
var errorType = new MathErrorFeature { MathError =
MathErrorType.NegativeRadicandError };
context.Features.Set(errorType);
return Results.BadRequest();
}
return Results.Ok(Math.Sqrt(radicand));
});
app.MapControllers();
app.Run();
Yukarıdaki kodda, en düşük API uç noktaları /divide
ve /squareroot
hata girişinde beklenen özel sorun yanıtını döndürür.
API denetleyicisi uç noktaları, özel sorun yanıtını değil hata girişinde varsayılan sorun yanıtını döndürür. API denetleyicisi yanıt akışına yazdığı için varsayılan sorun yanıtı döndürülür; hata durum kodları için sorun ayrıntıları, daha önce IProblemDetailsService.WriteAsync
çağrılır ve yanıt yeniden yazılmaz .
Aşağıdaki ValuesController
, yanıt akışına yazan ve bu nedenle özel sorun yanıtının döndürülmesini önleyen döndürür BadRequestResult.
[Route("api/[controller]/[action]")]
[ApiController]
public class ValuesController : ControllerBase
{
// /api/values/divide/1/2
[HttpGet("{Numerator}/{Denominator}")]
public IActionResult Divide(double Numerator, double Denominator)
{
if (Denominator == 0)
{
var errorType = new MathErrorFeature
{
MathError = MathErrorType.DivisionByZeroError
};
HttpContext.Features.Set(errorType);
return BadRequest();
}
return Ok(Numerator / Denominator);
}
// /api/values/squareroot/4
[HttpGet("{radicand}")]
public IActionResult Squareroot(double radicand)
{
if (radicand < 0)
{
var errorType = new MathErrorFeature
{
MathError = MathErrorType.NegativeRadicandError
};
HttpContext.Features.Set(errorType);
return BadRequest();
}
return Ok(Math.Sqrt(radicand));
}
}
Aşağıdaki Values3Controller
, beklenen özel sorun sonucunun döndürülmesi için döndürür ControllerBase.Problem
:
[Route("api/[controller]/[action]")]
[ApiController]
public class Values3Controller : ControllerBase
{
// /api/values3/divide/1/2
[HttpGet("{Numerator}/{Denominator}")]
public IActionResult Divide(double Numerator, double Denominator)
{
if (Denominator == 0)
{
var errorType = new MathErrorFeature
{
MathError = MathErrorType.DivisionByZeroError
};
HttpContext.Features.Set(errorType);
return Problem(
title: "Bad Input",
detail: "Divison by zero is not defined.",
type: "https://en.wikipedia.org/wiki/Division_by_zero",
statusCode: StatusCodes.Status400BadRequest
);
}
return Ok(Numerator / Denominator);
}
// /api/values3/squareroot/4
[HttpGet("{radicand}")]
public IActionResult Squareroot(double radicand)
{
if (radicand < 0)
{
var errorType = new MathErrorFeature
{
MathError = MathErrorType.NegativeRadicandError
};
HttpContext.Features.Set(errorType);
return Problem(
title: "Bad Input",
detail: "Negative or complex numbers are not valid input.",
type: "https://en.wikipedia.org/wiki/Square_root",
statusCode: StatusCodes.Status400BadRequest
);
}
return Ok(Math.Sqrt(radicand));
}
}
Özel durumlar için ProblemDetails yükü oluşturma
Aşağıdaki uygulamayı göz önünde bulundurun:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllers();
builder.Services.AddProblemDetails();
var app = builder.Build();
app.UseExceptionHandler();
app.UseStatusCodePages();
if (app.Environment.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.MapControllers();
app.Run();
Geliştirme dışı ortamlarda, bir özel durum oluştuğunda, istemciye döndürülen standart bir ProblemDetails yanıtı aşağıdadır:
{
"type":"https://tools.ietf.org/html/rfc7231#section-6.6.1",
"title":"An error occurred while processing your request.",
"status":500,"traceId":"00-b644<snip>-00"
}
Çoğu uygulama için, özel durumlar için gereken tek şey yukarıdaki koddur. Ancak aşağıdaki bölümde daha ayrıntılı sorun yanıtlarının nasıl alınıyor olduğu gösterilmektedir.
Özel özel durum işleyici sayfasının alternatifi, öğesine UseExceptionHandlerbir lambda sağlamaktır. Lambda kullanmak hataya erişim sağlar ve ile IProblemDetailsService.WriteAsync
bir sorun ayrıntıları yanıtı yazar:
using Microsoft.AspNetCore.Diagnostics;
using static System.Net.Mime.MediaTypeNames;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllers();
builder.Services.AddProblemDetails();
var app = builder.Build();
app.UseExceptionHandler();
app.UseStatusCodePages();
if (app.Environment.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler(exceptionHandlerApp =>
{
exceptionHandlerApp.Run(async context =>
{
context.Response.StatusCode = StatusCodes.Status500InternalServerError;
context.Response.ContentType = Text.Plain;
var title = "Bad Input";
var detail = "Invalid input";
var type = "https://errors.example.com/badInput";
if (context.RequestServices.GetService<IProblemDetailsService>() is
{ } problemDetailsService)
{
var exceptionHandlerFeature =
context.Features.Get<IExceptionHandlerFeature>();
var exceptionType = exceptionHandlerFeature?.Error;
if (exceptionType != null &&
exceptionType.Message.Contains("infinity"))
{
title = "Argument exception";
detail = "Invalid input";
type = "https://errors.example.com/argumentException";
}
await problemDetailsService.WriteAsync(new ProblemDetailsContext
{
HttpContext = context,
ProblemDetails =
{
Title = title,
Detail = detail,
Type = type
}
});
}
});
});
}
app.MapControllers();
app.Run();
Uyarı
Hassas hata bilgilerini istemcilere sunma. Hata sunma bir güvenlik riskidir.
Sorun ayrıntıları oluşturmak için alternatif bir yaklaşım, özel durumları ve istemci hatalarını sorun ayrıntılarıyla eşlemek için kullanılabilecek üçüncü taraf NuGet paketini Hellang.Middleware.ProblemDetails kullanmaktır.
Ek kaynaklar
Tarafından Tom Dykstra
Bu makalede, ASP.NET Core web uygulamalarında hataları işlemeye yönelik yaygın yaklaşımlar ele alınıyor. Ayrıca bkz. ASP.NET Core denetleyici tabanlı web API'lerindeki hataları işleme ve Minimum API'lerdeki hataları işleme.
Geliştirici özel durum sayfası
Geliştirici Özel Durum Sayfası, işlenmeyen istek özel durumları hakkında ayrıntılı bilgiler görüntüler. ASP.NET Core uygulamaları, her ikisi de aşağıdaki durumlarda varsayılan olarak geliştirici özel durum sayfasını etkinleştirir:
- Geliştirme ortamında çalıştırılıyor.
- Geçerli şablonlarla, yani WebApplication.CreateBuilder kullanılarak oluşturulan uygulama. kullanılarak oluşturulan uygulamalar,
WebHost.CreateDefaultBuilder
içindeConfigure
arayarakapp.UseDeveloperExceptionPage
geliştirici özel durum sayfasını etkinleştirmelidir.
Geliştirici özel durum sayfası ara yazılım işlem hattında erken çalıştırılır, böylece izleyen ara yazılımda işlenmeyen özel durumları yakalayabilir.
Uygulama Üretim ortamında çalıştırıldığında ayrıntılı özel durum bilgileri genel olarak görüntülenmemelidir. Ortamları yapılandırma hakkında daha fazla bilgi için bkz . ASP.NET Core'da birden çok ortam kullanma.
Geliştirici Özel Durum Sayfası, özel durum ve istek hakkında aşağıdaki bilgileri içerebilir:
- Yığın izleme
- Varsa sorgu dizesi parametreleri
- Varsa tanımlama bilgileri
- Üst Bilgiler
Geliştirici Özel Durum Sayfası'nın herhangi bir bilgi sağlaması garanti değildir. Tam hata bilgileri için Günlüğe Kaydetme özelliğini kullanın.
Özel durum işleyici sayfası
Üretim ortamı için özel bir hata işleme sayfası yapılandırmak için öğesini çağırınUseExceptionHandler. Ara yazılımı işleyen bu özel durum:
- İşlenmeyen özel durumları yakalar ve günlüğe kaydeder.
- Belirtilen yolu kullanarak isteği alternatif bir işlem hattında yeniden yürütür. Yanıt başlatıldıysa istek yeniden yürütülemez. Şablon tarafından oluşturulan kod, yolu kullanarak isteği yeniden yürütür
/Error
.
Uyarı
Alternatif işlem hattı kendi özel durumu oluşturursa, Özel Durum İşleme Ara Yazılımı özgün özel durumu yeniden oluşturur.
Bu ara yazılım istek işlem hattını yeniden yürütebileceğinden:
- Ara yazılımların yeniden giriş işlemini aynı istekle işlemesi gerekir. Bu normalde, çağrısından
_next
sonra durumlarını temizleme veya işlemi yeniden yapmaktan kaçınmak için üzerindeki işlemleriniHttpContext
önbelleğe alma anlamına gelir. İstek gövdesiyle ilgilenirken bu, Sonuçları Form okuyucusu gibi arabelleğe alma veya önbelleğe alma anlamına gelir. - UseExceptionHandler(IApplicationBuilder, String) Şablonlarda kullanılan aşırı yükleme için yalnızca istek yolu değiştirilir ve yol verileri temizlenir. Üst bilgiler, yöntem ve öğeler gibi istek verilerinin tümü olduğu gibi yeniden kullanılır.
- Kapsamı belirlenmiş hizmetler aynı kalır.
Aşağıdaki örnekte, UseExceptionHandler Geliştirme dışı ortamlarda özel durum işleme ara yazılımını ekler:
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
Sayfalar uygulama şablonu, Razor Sayfalar klasöründe bir Hata sayfası (.cshtml
) ve PageModel sınıf (ErrorModel
) sağlar. Bir MVC uygulaması için proje şablonu, denetleyici için Home bir Error
eylem yöntemi ve Hata görünümü içerir.
Özel durum işleme ara yazılımı özgün HTTP yöntemini kullanarak isteği yeniden yürütür. Hata işleyicisi uç noktası belirli bir HTTP yöntemleri kümesiyle sınırlıysa, yalnızca bu HTTP yöntemleri için çalışır. Örneğin, özniteliğini kullanan [HttpGet]
bir MVC denetleyicisi eylemi yalnızca GET istekleri için çalıştırılır. Tüm isteklerin özel hata işleme sayfasına ulaştığından emin olmak için bunları belirli bir HTTP yöntemleri kümesiyle kısıtlamayın.
Özel durumları özgün HTTP yöntemine göre farklı şekilde işlemek için:
- Sayfalar için Razor birden çok işleyici yöntemi oluşturun. Örneğin, GET özel durumlarını işlemek için kullanın
OnGet
ve POST özel durumlarını işlemek için kullanınOnPost
. - MVC için, birden çok eyleme HTTP fiili öznitelikleri uygulayın. Örneğin, GET özel durumlarını işlemek için kullanın
[HttpGet]
ve POST özel durumlarını işlemek için kullanın[HttpPost]
.
Kimliği doğrulanmamış kullanıcıların özel hata işleme sayfasını görüntülemesine izin vermek için anonim erişimi desteklediğinden emin olun.
Özel duruma erişme
Hata işleyicisinde özel duruma ve özgün istek yoluna erişmek için kullanın IExceptionHandlerPathFeature . Aşağıdaki örnek, oluşturulan özel durum hakkında daha fazla bilgi almak için kullanır IExceptionHandlerPathFeature
:
[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
[IgnoreAntiforgeryToken]
public class ErrorModel : PageModel
{
public string? RequestId { get; set; }
public bool ShowRequestId => !string.IsNullOrEmpty(RequestId);
public string? ExceptionMessage { get; set; }
public void OnGet()
{
RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier;
var exceptionHandlerPathFeature =
HttpContext.Features.Get<IExceptionHandlerPathFeature>();
if (exceptionHandlerPathFeature?.Error is FileNotFoundException)
{
ExceptionMessage = "The file was not found.";
}
if (exceptionHandlerPathFeature?.Path == "/")
{
ExceptionMessage ??= string.Empty;
ExceptionMessage += " Page: Home.";
}
}
}
Uyarı
Hassas hata bilgilerini istemcilere sunma. Hata sunma bir güvenlik riskidir.
Özel durum işleyici lambda
Özel özel durum işleyici sayfasının alternatifi, öğesine UseExceptionHandlerbir lambda sağlamaktır. Lambda kullanmak, yanıtı döndürmeden önce hataya erişim sağlar.
Aşağıdaki kod özel durum işleme için bir lambda kullanır:
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler(exceptionHandlerApp =>
{
exceptionHandlerApp.Run(async context =>
{
context.Response.StatusCode = StatusCodes.Status500InternalServerError;
// using static System.Net.Mime.MediaTypeNames;
context.Response.ContentType = Text.Plain;
await context.Response.WriteAsync("An exception was thrown.");
var exceptionHandlerPathFeature =
context.Features.Get<IExceptionHandlerPathFeature>();
if (exceptionHandlerPathFeature?.Error is FileNotFoundException)
{
await context.Response.WriteAsync(" The file was not found.");
}
if (exceptionHandlerPathFeature?.Path == "/")
{
await context.Response.WriteAsync(" Page: Home.");
}
});
});
app.UseHsts();
}
Uyarı
Hassas hata bilgilerini istemcilere sunma. Hata sunma bir güvenlik riskidir.
IExceptionHandler
IExceptionHandler , geliştiriciye merkezi bir konumda bilinen özel durumları işlemek için geri çağırma sağlayan bir arabirimdir.
IExceptionHandler
uygulamaları çağrılarak IServiceCollection.AddExceptionHandler<T>
kaydedilir. Bir IExceptionHandler
örneğin ömrü tekildir. Birden çok uygulama eklenebilir ve bunlar kayıtlı sırayla çağrılır.
Bir özel durum işleyicisi bir isteği işlerse, işlemeyi durdurmak için geri dönebilir true
. Bir özel durum işleyicisi herhangi bir özel durum işleyicisi tarafından işlenmezse denetim, ara yazılımdaki varsayılan davranışa ve seçeneklere geri döner. İşlenen ve işlenmeyen özel durumlar için farklı ölçümler ve günlükler yayılır.
Aşağıdaki örnekte bir IExceptionHandler
uygulama gösterilmektedir:
using Microsoft.AspNetCore.Diagnostics;
namespace ErrorHandlingSample
{
public class CustomExceptionHandler : IExceptionHandler
{
private readonly ILogger<CustomExceptionHandler> logger;
public CustomExceptionHandler(ILogger<CustomExceptionHandler> logger)
{
this.logger = logger;
}
public ValueTask<bool> TryHandleAsync(
HttpContext httpContext,
Exception exception,
CancellationToken cancellationToken)
{
var exceptionMessage = exception.Message;
logger.LogError(
"Error Message: {exceptionMessage}, Time of occurrence {time}",
exceptionMessage, DateTime.UtcNow);
// Return false to continue with the default behavior
// - or - return true to signal that this exception is handled
return ValueTask.FromResult(false);
}
}
}
Aşağıdaki örnekte, bağımlılık ekleme için bir IExceptionHandler
uygulamanın nasıl kaydedilecekleri gösterilmektedir:
using ErrorHandlingSample;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddDatabaseDeveloperPageExceptionFilter();
builder.Services.AddRazorPages();
builder.Services.AddExceptionHandler<CustomExceptionHandler>();
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
// Remaining Program.cs code omitted for brevity
Yukarıdaki kod Geliştirme ortamında çalıştırıldığında:
CustomExceptionHandler
bir özel durumu işlemek için ilk olarak çağrılır.- Özel durumu günlüğe kaydettikten sonra yöntemi döndürür
false
,TryHandleException
bu nedenle geliştirici özel durum sayfası gösterilir.
Diğer ortamlarda:
CustomExceptionHandler
bir özel durumu işlemek için ilk olarak çağrılır.- Özel durumu
TryHandleException
günlüğe kaydettikten sonra yöntemi döndürürfalse
, böylece/Error
sayfa gösterilir.
UseStatusCodePages
Varsayılan olarak, ASP.NET Core uygulaması HTTP hata durum kodları için 404 - Bulunamadı gibi bir durum kodu sayfası sağlamaz. Uygulama gövdesi olmayan bir HTTP 400-599 hata durum kodu ayarladığında, durum kodunu ve boş bir yanıt gövdesini döndürür. Yaygın hata durum kodları için varsayılan yalnızca metin işleyicilerini etkinleştirmek için çağrısında UseStatusCodePages kullanın Program.cs
:
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseStatusCodePages();
İstek işleme ara yazılımından önce çağırın UseStatusCodePages
. Örneğin, Statik Dosya Ara Yazılımı ve Uç Noktalar Ara Yazılımı'nın önünde çağırın UseStatusCodePages
.
Kullanılmadığında UseStatusCodePages
, uç nokta olmadan URL'ye gitmek, uç noktanın bulunamadığını belirten tarayıcıya bağlı bir hata iletisi döndürür. Çağrıldığında UseStatusCodePages
, tarayıcı aşağıdaki yanıtı döndürür:
Status Code: 404; Not Found
UseStatusCodePages
genellikle üretimde kullanılmaz çünkü kullanıcılar için yararlı olmayan bir ileti döndürür.
Not
Durum kodu sayfaları ara yazılımı özel durumları yakalamaz. Özel hata işleme sayfası sağlamak için özel durum işleyici sayfasını kullanın.
Biçim dizesi ile UseStatusCodePages
Yanıt içerik türünü ve metnini özelleştirmek için, bir içerik türü ve biçim dizesi alan öğesinin aşırı yüklemesini UseStatusCodePages kullanın:
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
// using static System.Net.Mime.MediaTypeNames;
app.UseStatusCodePages(Text.Plain, "Status Code Page: {0}");
Yukarıdaki kodda, {0}
hata kodu için bir yer tutucudur.
UseStatusCodePages
kullanıcılar için yararlı olmayan bir ileti döndürdüğü için, biçim dizesi genellikle üretimde kullanılmaz.
Lambda ile UseStatusCodePages
Özel hata işleme ve yanıt yazma kodu belirtmek için bir lambda ifadesi alan öğesinin aşırı yüklemesini UseStatusCodePages kullanın:
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseStatusCodePages(async statusCodeContext =>
{
// using static System.Net.Mime.MediaTypeNames;
statusCodeContext.HttpContext.Response.ContentType = Text.Plain;
await statusCodeContext.HttpContext.Response.WriteAsync(
$"Status Code Page: {statusCodeContext.HttpContext.Response.StatusCode}");
});
UseStatusCodePages
lambda ile genellikle üretimde kullanılmaz çünkü kullanıcılar için yararlı olmayan bir ileti döndürür.
UseStatusCodePagesWithRedirects
UseStatusCodePagesWithRedirects Uzantı yöntemi:
- İstemciye bir 302 - Bulundu durum kodu gönderir.
- İstemciyi URL şablonunda sağlanan hata işleme uç noktasına yönlendirir. Hata işleme uç noktası genellikle hata bilgilerini görüntüler ve HTTP 200 döndürür.
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseStatusCodePagesWithRedirects("/StatusCode/{0}");
URL şablonu, önceki kodda gösterildiği gibi durum kodu için bir {0}
yer tutucu içerebilir. URL şablonu (tilde) ile ~
başlıyorsa, ~
yerine uygulamanın PathBase
olur. Uygulamada bir uç nokta belirtirken, uç nokta için bir MVC görünümü veya Razor sayfası oluşturun.
Bu yöntem genellikle uygulama şu durumlarda kullanılır:
- genellikle farklı bir uygulamanın hatayı işlediği durumlarda istemciyi farklı bir uç noktaya yönlendirmelidir. Web uygulamaları için istemcinin tarayıcı adres çubuğu yeniden yönlendirilen uç noktayı yansıtır.
- İlk yeniden yönlendirme yanıtıyla özgün durum kodunu korumamalı ve döndürmemelidir.
UseStatusCodePagesWithReExecute
UseStatusCodePagesWithReExecute Uzantı yöntemi:
- Alternatif bir yol kullanarak istek işlem hattını yeniden yürüterek yanıt gövdesini oluşturur.
- İşlem hattı yeniden yürütülmeden önce veya sonra durum kodunu değiştirmez.
Yeni işlem hattı, durum kodu üzerinde tam denetime sahip olduğundan yeni işlem hattı yürütmesi yanıtın durum kodunu değiştirebilir. Yeni işlem hattı durum kodunu değiştirmezse, özgün durum kodu istemciye gönderilir.
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseStatusCodePagesWithReExecute("/StatusCode/{0}");
Uygulama içinde bir uç nokta belirtilirse, uç nokta için bir MVC görünümü veya Razor sayfası oluşturun.
Bu yöntem genellikle uygulamanın aşağıdakileri yapması gerektiğinde kullanılır:
- İsteği farklı bir uç noktaya yeniden yönlendirmeden işleyin. Web uygulamaları için istemcinin tarayıcı adres çubuğu başlangıçta istenen uç noktayı yansıtır.
- Yanıtla birlikte özgün durum kodunu koruyun ve döndürin.
URL şablonu ile /
başlamalıdır ve durum kodu için bir yer tutucu {0}
içerebilir. Durum kodunu sorgu dizesi parametresi olarak geçirmek için içine ikinci bir bağımsız değişken UseStatusCodePagesWithReExecute
geçirin. Örneğin:
var app = builder.Build();
app.UseStatusCodePagesWithReExecute("/StatusCode", "?statusCode={0}");
Hatayı işleyen uç nokta, aşağıdaki örnekte gösterildiği gibi hatayı oluşturan özgün URL'yi alabilir:
[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
public class StatusCodeModel : PageModel
{
public int OriginalStatusCode { get; set; }
public string? OriginalPathAndQuery { get; set; }
public void OnGet(int statusCode)
{
OriginalStatusCode = statusCode;
var statusCodeReExecuteFeature =
HttpContext.Features.Get<IStatusCodeReExecuteFeature>();
if (statusCodeReExecuteFeature is not null)
{
OriginalPathAndQuery = $"{statusCodeReExecuteFeature.OriginalPathBase}"
+ $"{statusCodeReExecuteFeature.OriginalPath}"
+ $"{statusCodeReExecuteFeature.OriginalQueryString}";
}
}
}
Bu ara yazılım istek işlem hattını yeniden yürütebileceğinden:
- Ara yazılımların yeniden giriş işlemini aynı istekle işlemesi gerekir. Bu normalde, çağrısından
_next
sonra durumlarını temizleme veya işlemi yeniden yapmaktan kaçınmak için üzerindeki işlemleriniHttpContext
önbelleğe alma anlamına gelir. İstek gövdesiyle ilgilenirken bu, Sonuçları Form okuyucusu gibi arabelleğe alma veya önbelleğe alma anlamına gelir. - Kapsamı belirlenmiş hizmetler aynı kalır.
Durum kodu sayfalarını devre dışı bırakma
MVC denetleyicisinin veya eylem yönteminin durum kodu sayfalarını devre dışı bırakmak için [SkipStatusCodePages] özniteliğini kullanın.
Pages işleyici yönteminde veya MVC denetleyicisinde Razor belirli istekler için durum kodu sayfalarını devre dışı bırakmak için kullanın IStatusCodePagesFeature:
public void OnGet()
{
var statusCodePagesFeature =
HttpContext.Features.Get<IStatusCodePagesFeature>();
if (statusCodePagesFeature is not null)
{
statusCodePagesFeature.Enabled = false;
}
}
Özel durum işleme kodu
Özel durum işleme sayfalarındaki kod da özel durumlar oluşturabilir. Üretim hata sayfaları kapsamlı bir şekilde test edilmeli ve kendi özel durumlarının oluşmasını önlemek için ek özen gösterilmelidir.
Yanıt üst bilgileri
Yanıtın üst bilgileri gönderildikten sonra:
- Uygulama yanıtın durum kodunu değiştiremez.
- Özel durum sayfaları veya işleyicileri çalıştırılamaz. Yanıt tamamlanmalıdır veya bağlantı durdurulmalıdır.
Sunucu özel durum işleme
Bir uygulamadaki özel durum işleme mantığına ek olarak, HTTP sunucusu uygulaması bazı özel durumları işleyebilir. Sunucu yanıt üst bilgileri gönderilmeden önce bir özel durum yakalarsa, yanıt gövdesi olmadan bir 500 - Internal Server Error
yanıt gönderir. Yanıt üst bilgileri gönderildikten sonra sunucu bir özel durum yakalarsa, sunucu bağlantıyı kapatır. Uygulama tarafından işlenmemiş istekler sunucu tarafından işlenir. Sunucu isteği işlerken oluşan özel durumlar, sunucunun özel durum işlemesi tarafından işlenir. Uygulamanın özel hata sayfaları, özel durum işleme ara yazılımı ve filtreler bu davranışı etkilemez.
Özel durum işlemeyi başlatma
Yalnızca barındırma katmanı, uygulama başlatma sırasında gerçekleşen özel durumları işleyebilir. Konak, başlangıç hatalarını yakalamak ve ayrıntılı hataları yakalamak için yapılandırılabilir.
Barındırma katmanı, yakalanan başlatma hatası için yalnızca ana bilgisayar adresi/bağlantı noktası bağlaması sonrasında hata oluşması durumunda bir hata sayfası gösterebilir. Bağlama başarısız olursa:
- Barındırma katmanı kritik bir özel durumu günlüğe kaydeder.
- dotnet işlemi kilitleniyor.
- HTTP sunucusu olduğunda hiçbir hata sayfası görüntülenmez Kestrel.
IIS (veya Azure Uygulaması Hizmeti) veya IIS Express üzerinde çalışırken, işlem başlatılamıyorsa ASP.NET Çekirdek Modülü tarafından 502.5 - İşlem Hatası döndürülür. Daha fazla bilgi için bkz. Azure Uygulaması Hizmeti ve IIS'de ASP.NET Core sorunlarını giderme.
Veritabanı hata sayfası
Veritabanı geliştirici sayfası özel durum filtresi AddDatabaseDeveloperPageExceptionFilter , Entity Framework Core geçişleri kullanılarak çözümlenebilen veritabanıyla ilgili özel durumları yakalar. Bu özel durumlar oluştuğunda, sorunu çözmek için olası eylemlerin ayrıntılarıyla birlikte bir HTML yanıtı oluşturulur. Bu sayfa yalnızca Geliştirme ortamında etkinleştirilir. Aşağıdaki kod, Veritabanı geliştirici sayfası özel durum filtresini ekler:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddDatabaseDeveloperPageExceptionFilter();
builder.Services.AddRazorPages();
Özel durum filtreleri
MVC uygulamalarında özel durum filtreleri genel olarak veya denetleyici başına veya eylem temelinde yapılandırılabilir. Razor Sayfalar uygulamalarında, bunlar genel olarak veya sayfa modeli başına yapılandırılabilir. Bu filtreler, bir denetleyici eyleminin veya başka bir filtrenin yürütülmesi sırasında oluşan işlenmeyen özel durumları işler. Daha fazla bilgi için bkz . ASP.NET Core'daki filtreler.
Özel durum filtreleri, MVC eylemleri içinde oluşan özel durumları yakalamak için kullanışlıdır, ancak yerleşik özel durum işleme ara yazılımıUseExceptionHandler kadar esnek değildir. Hangi MVC eyleminin seçildiğine göre farklı hata işleme gerçekleştirmeniz gerekmediği sürece kullanmanızı UseExceptionHandler
öneririz.
Model durumu hataları
Model durumu hatalarını işleme hakkında bilgi için bkz . Model bağlama ve Model doğrulama.
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(IServiceCollection) ü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çermemesiAccept
dışı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
- ExceptionHandlerMiddleware: Özel işleyici tanımlanmadığında bir sorun ayrıntıları yanıtı oluşturur.
- StatusCodePagesMiddleware: Varsayılan olarak bir sorun ayrıntıları yanıtı oluşturur.
- DeveloperExceptionPageMiddleware: İstek HTTP üst bilgisi içermediğinde
Accept
text/html
geliştirme aşamasında bir sorun ayrıntıları yanıtı oluşturur.
Aşağıdaki kod, uygulamayı henüz gövde içeriği olmayan tüm HTTP istemcisi ve sunucu hata yanıtları için bir sorun ayrıntıları yanıtı oluşturacak şekilde yapılandırır:
builder.Services.AddProblemDetails();
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler();
app.UseHsts();
}
app.UseStatusCodePages();
Sonraki bölümde sorun ayrıntıları yanıt gövdesinin nasıl özelleştirileceği gösterilmektedir.
Sorun ayrıntılarını özelleştirme
öğesinin ProblemDetails
otomatik olarak oluşturulması, aşağıdaki seçeneklerden herhangi biri kullanılarak özelleştirilebilir:
ProblemDetailsOptions.CustomizeProblemDetails
komutunu kullanma- Özel kullanım
IProblemDetailsWriter
- ara yazılımda öğesini
IProblemDetailsService
çağırma
CustomizeProblemDetails
işlem
Oluşturulan sorun ayrıntıları kullanılarak CustomizeProblemDetailsözelleştirilebilir ve özelleştirmeler otomatik olarak oluşturulan tüm sorun ayrıntılarına uygulanır.
Ayarlamak için CustomizeProblemDetailsaşağıdaki kod kullanılırProblemDetailsOptions:
builder.Services.AddProblemDetails(options =>
options.CustomizeProblemDetails = ctx =>
ctx.ProblemDetails.Extensions.Add("nodeId", Environment.MachineName));
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler();
app.UseHsts();
}
app.UseStatusCodePages();
Örneğin, bir HTTP Status 400 Bad Request
uç nokta sonucu aşağıdaki sorun ayrıntıları yanıt gövdesini oluşturur:
{
"type": "https://tools.ietf.org/html/rfc9110#section-15.5.1",
"title": "Bad Request",
"status": 400,
"nodeId": "my-machine-name"
}
Töre IProblemDetailsWriter
Gelişmiş özelleştirmeler için bir IProblemDetailsWriter uygulama oluşturulabilir.
public class SampleProblemDetailsWriter : IProblemDetailsWriter
{
// Indicates that only responses with StatusCode == 400
// are handled by this writer. All others are
// handled by different registered writers if available.
public bool CanWrite(ProblemDetailsContext context)
=> context.HttpContext.Response.StatusCode == 400;
public ValueTask WriteAsync(ProblemDetailsContext context)
{
// Additional customizations.
// Write to the response.
var response = context.HttpContext.Response;
return new ValueTask(response.WriteAsJsonAsync(context.ProblemDetails));
}
}
Not: Özel IProblemDetailsWriter
kullanılırken, özel IProblemDetailsWriter
öğesinin , , AddControllersWithViewsAddControllersveya AddMvcçağrılmadan AddRazorPagesönce kaydedilmesi gerekir:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddTransient<IProblemDetailsWriter, SampleProblemDetailsWriter>();
var app = builder.Build();
// Middleware to handle writing problem details to the response.
app.Use(async (context, next) =>
{
await next(context);
var mathErrorFeature = context.Features.Get<MathErrorFeature>();
if (mathErrorFeature is not null)
{
if (context.RequestServices.GetService<IProblemDetailsWriter>() is
{ } problemDetailsService)
{
if (problemDetailsService.CanWrite(new ProblemDetailsContext() { HttpContext = context }))
{
(string Detail, string Type) details = mathErrorFeature.MathError switch
{
MathErrorType.DivisionByZeroError => ("Divison by zero is not defined.",
"https://en.wikipedia.org/wiki/Division_by_zero"),
_ => ("Negative or complex numbers are not valid input.",
"https://en.wikipedia.org/wiki/Square_root")
};
await problemDetailsService.WriteAsync(new ProblemDetailsContext
{
HttpContext = context,
ProblemDetails =
{
Title = "Bad Input",
Detail = details.Detail,
Type = details.Type
}
});
}
}
}
});
// /divide?numerator=2&denominator=4
app.MapGet("/divide", (HttpContext context, double numerator, double denominator) =>
{
if (denominator == 0)
{
var errorType = new MathErrorFeature
{
MathError = MathErrorType.DivisionByZeroError
};
context.Features.Set(errorType);
return Results.BadRequest();
}
return Results.Ok(numerator / denominator);
});
// /squareroot?radicand=16
app.MapGet("/squareroot", (HttpContext context, double radicand) =>
{
if (radicand < 0)
{
var errorType = new MathErrorFeature
{
MathError = MathErrorType.NegativeRadicandError
};
context.Features.Set(errorType);
return Results.BadRequest();
}
return Results.Ok(Math.Sqrt(radicand));
});
app.Run();
Ara Yazılımdan sorun ayrıntıları
ile CustomizeProblemDetails kullanmak ProblemDetailsOptions için alternatif bir yaklaşım, ara yazılımı ayarlamaktırProblemDetails. Bir sorun ayrıntıları yanıtı çağrılarak IProblemDetailsService.WriteAsync
yazılabilir:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllers();
builder.Services.AddProblemDetails();
var app = builder.Build();
app.UseHttpsRedirection();
app.UseStatusCodePages();
// Middleware to handle writing problem details to the response.
app.Use(async (context, next) =>
{
await next(context);
var mathErrorFeature = context.Features.Get<MathErrorFeature>();
if (mathErrorFeature is not null)
{
if (context.RequestServices.GetService<IProblemDetailsService>() is
{ } problemDetailsService)
{
(string Detail, string Type) details = mathErrorFeature.MathError switch
{
MathErrorType.DivisionByZeroError => ("Divison by zero is not defined.",
"https://en.wikipedia.org/wiki/Division_by_zero"),
_ => ("Negative or complex numbers are not valid input.",
"https://en.wikipedia.org/wiki/Square_root")
};
await problemDetailsService.WriteAsync(new ProblemDetailsContext
{
HttpContext = context,
ProblemDetails =
{
Title = "Bad Input",
Detail = details.Detail,
Type = details.Type
}
});
}
}
});
// /divide?numerator=2&denominator=4
app.MapGet("/divide", (HttpContext context, double numerator, double denominator) =>
{
if (denominator == 0)
{
var errorType = new MathErrorFeature { MathError =
MathErrorType.DivisionByZeroError };
context.Features.Set(errorType);
return Results.BadRequest();
}
return Results.Ok(numerator / denominator);
});
// /squareroot?radicand=16
app.MapGet("/squareroot", (HttpContext context, double radicand) =>
{
if (radicand < 0)
{
var errorType = new MathErrorFeature { MathError =
MathErrorType.NegativeRadicandError };
context.Features.Set(errorType);
return Results.BadRequest();
}
return Results.Ok(Math.Sqrt(radicand));
});
app.MapControllers();
app.Run();
Yukarıdaki kodda, en düşük API uç noktaları /divide
ve /squareroot
hata girişinde beklenen özel sorun yanıtını döndürür.
API denetleyicisi uç noktaları, özel sorun yanıtını değil hata girişinde varsayılan sorun yanıtını döndürür. API denetleyicisi yanıt akışına yazdığı için varsayılan sorun yanıtı döndürülür; hata durum kodları için sorun ayrıntıları, daha önce IProblemDetailsService.WriteAsync
çağrılır ve yanıt yeniden yazılmaz .
Aşağıdaki ValuesController
, yanıt akışına yazan ve bu nedenle özel sorun yanıtının döndürülmesini önleyen döndürür BadRequestResult.
[Route("api/[controller]/[action]")]
[ApiController]
public class ValuesController : ControllerBase
{
// /api/values/divide/1/2
[HttpGet("{Numerator}/{Denominator}")]
public IActionResult Divide(double Numerator, double Denominator)
{
if (Denominator == 0)
{
var errorType = new MathErrorFeature
{
MathError = MathErrorType.DivisionByZeroError
};
HttpContext.Features.Set(errorType);
return BadRequest();
}
return Ok(Numerator / Denominator);
}
// /api/values/squareroot/4
[HttpGet("{radicand}")]
public IActionResult Squareroot(double radicand)
{
if (radicand < 0)
{
var errorType = new MathErrorFeature
{
MathError = MathErrorType.NegativeRadicandError
};
HttpContext.Features.Set(errorType);
return BadRequest();
}
return Ok(Math.Sqrt(radicand));
}
}
Aşağıdaki Values3Controller
, beklenen özel sorun sonucunun döndürülmesi için döndürür ControllerBase.Problem
:
[Route("api/[controller]/[action]")]
[ApiController]
public class Values3Controller : ControllerBase
{
// /api/values3/divide/1/2
[HttpGet("{Numerator}/{Denominator}")]
public IActionResult Divide(double Numerator, double Denominator)
{
if (Denominator == 0)
{
var errorType = new MathErrorFeature
{
MathError = MathErrorType.DivisionByZeroError
};
HttpContext.Features.Set(errorType);
return Problem(
title: "Bad Input",
detail: "Divison by zero is not defined.",
type: "https://en.wikipedia.org/wiki/Division_by_zero",
statusCode: StatusCodes.Status400BadRequest
);
}
return Ok(Numerator / Denominator);
}
// /api/values3/squareroot/4
[HttpGet("{radicand}")]
public IActionResult Squareroot(double radicand)
{
if (radicand < 0)
{
var errorType = new MathErrorFeature
{
MathError = MathErrorType.NegativeRadicandError
};
HttpContext.Features.Set(errorType);
return Problem(
title: "Bad Input",
detail: "Negative or complex numbers are not valid input.",
type: "https://en.wikipedia.org/wiki/Square_root",
statusCode: StatusCodes.Status400BadRequest
);
}
return Ok(Math.Sqrt(radicand));
}
}
Özel durumlar için ProblemDetails yükü oluşturma
Aşağıdaki uygulamayı göz önünde bulundurun:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllers();
builder.Services.AddProblemDetails();
var app = builder.Build();
app.UseExceptionHandler();
app.UseStatusCodePages();
if (app.Environment.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.MapControllers();
app.Run();
Geliştirme dışı ortamlarda, bir özel durum oluştuğunda, istemciye döndürülen standart bir ProblemDetails yanıtı aşağıdadır:
{
"type":"https://tools.ietf.org/html/rfc7231#section-6.6.1",
"title":"An error occurred while processing your request.",
"status":500,"traceId":"00-b644<snip>-00"
}
Çoğu uygulama için, özel durumlar için gereken tek şey yukarıdaki koddur. Ancak aşağıdaki bölümde daha ayrıntılı sorun yanıtlarının nasıl alınıyor olduğu gösterilmektedir.
Özel özel durum işleyici sayfasının alternatifi, öğesine UseExceptionHandlerbir lambda sağlamaktır. Lambda kullanmak hataya erişim sağlar ve ile IProblemDetailsService.WriteAsync
bir sorun ayrıntıları yanıtı yazar:
using Microsoft.AspNetCore.Diagnostics;
using static System.Net.Mime.MediaTypeNames;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllers();
builder.Services.AddProblemDetails();
var app = builder.Build();
app.UseExceptionHandler();
app.UseStatusCodePages();
if (app.Environment.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler(exceptionHandlerApp =>
{
exceptionHandlerApp.Run(async context =>
{
context.Response.StatusCode = StatusCodes.Status500InternalServerError;
context.Response.ContentType = Text.Plain;
var title = "Bad Input";
var detail = "Invalid input";
var type = "https://errors.example.com/badInput";
if (context.RequestServices.GetService<IProblemDetailsService>() is
{ } problemDetailsService)
{
var exceptionHandlerFeature =
context.Features.Get<IExceptionHandlerFeature>();
var exceptionType = exceptionHandlerFeature?.Error;
if (exceptionType != null &&
exceptionType.Message.Contains("infinity"))
{
title = "Argument exception";
detail = "Invalid input";
type = "https://errors.example.com/argumentException";
}
await problemDetailsService.WriteAsync(new ProblemDetailsContext
{
HttpContext = context,
ProblemDetails =
{
Title = title,
Detail = detail,
Type = type
}
});
}
});
});
}
app.MapControllers();
app.Run();
Uyarı
Hassas hata bilgilerini istemcilere sunma. Hata sunma bir güvenlik riskidir.
Sorun ayrıntıları oluşturmak için alternatif bir yaklaşım, özel durumları ve istemci hatalarını sorun ayrıntılarıyla eşlemek için kullanılabilecek üçüncü taraf NuGet paketini Hellang.Middleware.ProblemDetails kullanmaktır.
Ek kaynaklar
Tarafından Tom Dykstra
Bu makalede, ASP.NET Core web uygulamalarında hataları işlemeye yönelik yaygın yaklaşımlar ele alınıyor. Ayrıca bkz. ASP.NET Core denetleyici tabanlı web API'lerindeki hataları işleme ve Minimum API'lerdeki hataları işleme.
Geliştirici özel durum sayfası
Geliştirici Özel Durum Sayfası, işlenmeyen istek özel durumları hakkında ayrıntılı bilgiler görüntüler. ASP.NET Core uygulamaları, her ikisi de aşağıdaki durumlarda varsayılan olarak geliştirici özel durum sayfasını etkinleştirir:
- Geliştirme ortamında çalıştırılıyor.
- Geçerli şablonlarla, yani WebApplication.CreateBuilder kullanılarak oluşturulan uygulama. kullanılarak oluşturulan uygulamalar,
WebHost.CreateDefaultBuilder
içindeConfigure
arayarakapp.UseDeveloperExceptionPage
geliştirici özel durum sayfasını etkinleştirmelidir.
Geliştirici özel durum sayfası ara yazılım işlem hattında erken çalıştırılır, böylece izleyen ara yazılımda işlenmeyen özel durumları yakalayabilir.
Uygulama Üretim ortamında çalıştırıldığında ayrıntılı özel durum bilgileri genel olarak görüntülenmemelidir. Ortamları yapılandırma hakkında daha fazla bilgi için bkz . ASP.NET Core'da birden çok ortam kullanma.
Geliştirici Özel Durum Sayfası, özel durum ve istek hakkında aşağıdaki bilgileri içerebilir:
- Yığın izleme
- Varsa sorgu dizesi parametreleri
- Varsa tanımlama bilgileri
- Üst Bilgiler
Geliştirici Özel Durum Sayfası'nın herhangi bir bilgi sağlaması garanti değildir. Tam hata bilgileri için Günlüğe Kaydetme özelliğini kullanın.
Özel durum işleyici sayfası
Üretim ortamı için özel bir hata işleme sayfası yapılandırmak için öğesini çağırınUseExceptionHandler. Ara yazılımı işleyen bu özel durum:
- İşlenmeyen özel durumları yakalar ve günlüğe kaydeder.
- Belirtilen yolu kullanarak isteği alternatif bir işlem hattında yeniden yürütür. Yanıt başlatıldıysa istek yeniden yürütülemez. Şablon tarafından oluşturulan kod, yolu kullanarak isteği yeniden yürütür
/Error
.
Uyarı
Alternatif işlem hattı kendi özel durumu oluşturursa, Özel Durum İşleme Ara Yazılımı özgün özel durumu yeniden oluşturur.
Bu ara yazılım istek işlem hattını yeniden yürütebileceğinden:
- Ara yazılımların yeniden giriş işlemini aynı istekle işlemesi gerekir. Bu normalde, çağrısından
_next
sonra durumlarını temizleme veya işlemi yeniden yapmaktan kaçınmak için üzerindeki işlemleriniHttpContext
önbelleğe alma anlamına gelir. İstek gövdesiyle ilgilenirken bu, Sonuçları Form okuyucusu gibi arabelleğe alma veya önbelleğe alma anlamına gelir. - UseExceptionHandler(IApplicationBuilder, String) Şablonlarda kullanılan aşırı yükleme için yalnızca istek yolu değiştirilir ve yol verileri temizlenir. Üst bilgiler, yöntem ve öğeler gibi istek verilerinin tümü olduğu gibi yeniden kullanılır.
- Kapsamı belirlenmiş hizmetler aynı kalır.
Aşağıdaki örnekte, UseExceptionHandler Geliştirme dışı ortamlarda özel durum işleme ara yazılımını ekler:
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
Sayfalar uygulama şablonu, Razor Sayfalar klasöründe bir Hata sayfası (.cshtml
) ve PageModel sınıf (ErrorModel
) sağlar. Bir MVC uygulaması için proje şablonu, denetleyici için Home bir Error
eylem yöntemi ve Hata görünümü içerir.
Özel durum işleme ara yazılımı özgün HTTP yöntemini kullanarak isteği yeniden yürütür. Hata işleyicisi uç noktası belirli bir HTTP yöntemleri kümesiyle sınırlıysa, yalnızca bu HTTP yöntemleri için çalışır. Örneğin, özniteliğini kullanan [HttpGet]
bir MVC denetleyicisi eylemi yalnızca GET istekleri için çalıştırılır. Tüm isteklerin özel hata işleme sayfasına ulaştığından emin olmak için bunları belirli bir HTTP yöntemleri kümesiyle kısıtlamayın.
Özel durumları özgün HTTP yöntemine göre farklı şekilde işlemek için:
- Sayfalar için Razor birden çok işleyici yöntemi oluşturun. Örneğin, GET özel durumlarını işlemek için kullanın
OnGet
ve POST özel durumlarını işlemek için kullanınOnPost
. - MVC için, birden çok eyleme HTTP fiili öznitelikleri uygulayın. Örneğin, GET özel durumlarını işlemek için kullanın
[HttpGet]
ve POST özel durumlarını işlemek için kullanın[HttpPost]
.
Kimliği doğrulanmamış kullanıcıların özel hata işleme sayfasını görüntülemesine izin vermek için anonim erişimi desteklediğinden emin olun.
Özel duruma erişme
Hata işleyicisinde özel duruma ve özgün istek yoluna erişmek için kullanın IExceptionHandlerPathFeature . Aşağıdaki örnek, oluşturulan özel durum hakkında daha fazla bilgi almak için kullanır IExceptionHandlerPathFeature
:
[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
[IgnoreAntiforgeryToken]
public class ErrorModel : PageModel
{
public string? RequestId { get; set; }
public bool ShowRequestId => !string.IsNullOrEmpty(RequestId);
public string? ExceptionMessage { get; set; }
public void OnGet()
{
RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier;
var exceptionHandlerPathFeature =
HttpContext.Features.Get<IExceptionHandlerPathFeature>();
if (exceptionHandlerPathFeature?.Error is FileNotFoundException)
{
ExceptionMessage = "The file was not found.";
}
if (exceptionHandlerPathFeature?.Path == "/")
{
ExceptionMessage ??= string.Empty;
ExceptionMessage += " Page: Home.";
}
}
}
Uyarı
Hassas hata bilgilerini istemcilere sunma. Hata sunma bir güvenlik riskidir.
Özel durum işleyici lambda
Özel özel durum işleyici sayfasının alternatifi, öğesine UseExceptionHandlerbir lambda sağlamaktır. Lambda kullanmak, yanıtı döndürmeden önce hataya erişim sağlar.
Aşağıdaki kod özel durum işleme için bir lambda kullanır:
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler(exceptionHandlerApp =>
{
exceptionHandlerApp.Run(async context =>
{
context.Response.StatusCode = StatusCodes.Status500InternalServerError;
// using static System.Net.Mime.MediaTypeNames;
context.Response.ContentType = Text.Plain;
await context.Response.WriteAsync("An exception was thrown.");
var exceptionHandlerPathFeature =
context.Features.Get<IExceptionHandlerPathFeature>();
if (exceptionHandlerPathFeature?.Error is FileNotFoundException)
{
await context.Response.WriteAsync(" The file was not found.");
}
if (exceptionHandlerPathFeature?.Path == "/")
{
await context.Response.WriteAsync(" Page: Home.");
}
});
});
app.UseHsts();
}
Uyarı
Hassas hata bilgilerini istemcilere sunma. Hata sunma bir güvenlik riskidir.
UseStatusCodePages
Varsayılan olarak, ASP.NET Core uygulaması HTTP hata durum kodları için 404 - Bulunamadı gibi bir durum kodu sayfası sağlamaz. Uygulama gövdesi olmayan bir HTTP 400-599 hata durum kodu ayarladığında, durum kodunu ve boş bir yanıt gövdesini döndürür. Yaygın hata durum kodları için varsayılan yalnızca metin işleyicilerini etkinleştirmek için çağrısında UseStatusCodePages kullanın Program.cs
:
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseStatusCodePages();
İstek işleme ara yazılımından önce çağırın UseStatusCodePages
. Örneğin, Statik Dosya Ara Yazılımı ve Uç Noktalar Ara Yazılımı'nın önünde çağırın UseStatusCodePages
.
Kullanılmadığında UseStatusCodePages
, uç nokta olmadan URL'ye gitmek, uç noktanın bulunamadığını belirten tarayıcıya bağlı bir hata iletisi döndürür. Çağrıldığında UseStatusCodePages
, tarayıcı aşağıdaki yanıtı döndürür:
Status Code: 404; Not Found
UseStatusCodePages
genellikle üretimde kullanılmaz çünkü kullanıcılar için yararlı olmayan bir ileti döndürür.
Not
Durum kodu sayfaları ara yazılımı özel durumları yakalamaz. Özel hata işleme sayfası sağlamak için özel durum işleyici sayfasını kullanın.
Biçim dizesi ile UseStatusCodePages
Yanıt içerik türünü ve metnini özelleştirmek için, bir içerik türü ve biçim dizesi alan öğesinin aşırı yüklemesini UseStatusCodePages kullanın:
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
// using static System.Net.Mime.MediaTypeNames;
app.UseStatusCodePages(Text.Plain, "Status Code Page: {0}");
Yukarıdaki kodda, {0}
hata kodu için bir yer tutucudur.
UseStatusCodePages
kullanıcılar için yararlı olmayan bir ileti döndürdüğü için, biçim dizesi genellikle üretimde kullanılmaz.
Lambda ile UseStatusCodePages
Özel hata işleme ve yanıt yazma kodu belirtmek için bir lambda ifadesi alan öğesinin aşırı yüklemesini UseStatusCodePages kullanın:
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseStatusCodePages(async statusCodeContext =>
{
// using static System.Net.Mime.MediaTypeNames;
statusCodeContext.HttpContext.Response.ContentType = Text.Plain;
await statusCodeContext.HttpContext.Response.WriteAsync(
$"Status Code Page: {statusCodeContext.HttpContext.Response.StatusCode}");
});
UseStatusCodePages
lambda ile genellikle üretimde kullanılmaz çünkü kullanıcılar için yararlı olmayan bir ileti döndürür.
UseStatusCodePagesWithRedirects
UseStatusCodePagesWithRedirects Uzantı yöntemi:
- İstemciye bir 302 - Bulundu durum kodu gönderir.
- İstemciyi URL şablonunda sağlanan hata işleme uç noktasına yönlendirir. Hata işleme uç noktası genellikle hata bilgilerini görüntüler ve HTTP 200 döndürür.
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseStatusCodePagesWithRedirects("/StatusCode/{0}");
URL şablonu, önceki kodda gösterildiği gibi durum kodu için bir {0}
yer tutucu içerebilir. URL şablonu (tilde) ile ~
başlıyorsa, ~
yerine uygulamanın PathBase
olur. Uygulamada bir uç nokta belirtirken, uç nokta için bir MVC görünümü veya Razor sayfası oluşturun.
Bu yöntem genellikle uygulama şu durumlarda kullanılır:
- genellikle farklı bir uygulamanın hatayı işlediği durumlarda istemciyi farklı bir uç noktaya yönlendirmelidir. Web uygulamaları için istemcinin tarayıcı adres çubuğu yeniden yönlendirilen uç noktayı yansıtır.
- İlk yeniden yönlendirme yanıtıyla özgün durum kodunu korumamalı ve döndürmemelidir.
UseStatusCodePagesWithReExecute
UseStatusCodePagesWithReExecute Uzantı yöntemi:
- Alternatif bir yol kullanarak istek işlem hattını yeniden yürüterek yanıt gövdesini oluşturur.
- İşlem hattı yeniden yürütülmeden önce veya sonra durum kodunu değiştirmez.
Yeni işlem hattı, durum kodu üzerinde tam denetime sahip olduğundan yeni işlem hattı yürütmesi yanıtın durum kodunu değiştirebilir. Yeni işlem hattı durum kodunu değiştirmezse, özgün durum kodu istemciye gönderilir.
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseStatusCodePagesWithReExecute("/StatusCode/{0}");
Uygulama içinde bir uç nokta belirtilirse, uç nokta için bir MVC görünümü veya Razor sayfası oluşturun.
Bu yöntem genellikle uygulamanın aşağıdakileri yapması gerektiğinde kullanılır:
- İsteği farklı bir uç noktaya yeniden yönlendirmeden işleyin. Web uygulamaları için istemcinin tarayıcı adres çubuğu başlangıçta istenen uç noktayı yansıtır.
- Yanıtla birlikte özgün durum kodunu koruyun ve döndürin.
URL şablonu ile /
başlamalıdır ve durum kodu için bir yer tutucu {0}
içerebilir. Durum kodunu sorgu dizesi parametresi olarak geçirmek için içine ikinci bir bağımsız değişken UseStatusCodePagesWithReExecute
geçirin. Örneğin:
var app = builder.Build();
app.UseStatusCodePagesWithReExecute("/StatusCode", "?statusCode={0}");
Hatayı işleyen uç nokta, aşağıdaki örnekte gösterildiği gibi hatayı oluşturan özgün URL'yi alabilir:
[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
public class StatusCodeModel : PageModel
{
public int OriginalStatusCode { get; set; }
public string? OriginalPathAndQuery { get; set; }
public void OnGet(int statusCode)
{
OriginalStatusCode = statusCode;
var statusCodeReExecuteFeature =
HttpContext.Features.Get<IStatusCodeReExecuteFeature>();
if (statusCodeReExecuteFeature is not null)
{
OriginalPathAndQuery = $"{statusCodeReExecuteFeature.OriginalPathBase}"
+ $"{statusCodeReExecuteFeature.OriginalPath}"
+ $"{statusCodeReExecuteFeature.OriginalQueryString}";
}
}
}
Bu ara yazılım istek işlem hattını yeniden yürütebileceğinden:
- Ara yazılımların yeniden giriş işlemini aynı istekle işlemesi gerekir. Bu normalde, çağrısından
_next
sonra durumlarını temizleme veya işlemi yeniden yapmaktan kaçınmak için üzerindeki işlemleriniHttpContext
önbelleğe alma anlamına gelir. İstek gövdesiyle ilgilenirken bu, Sonuçları Form okuyucusu gibi arabelleğe alma veya önbelleğe alma anlamına gelir. - Kapsamı belirlenmiş hizmetler aynı kalır.
Durum kodu sayfalarını devre dışı bırakma
MVC denetleyicisinin veya eylem yönteminin durum kodu sayfalarını devre dışı bırakmak için [SkipStatusCodePages] özniteliğini kullanın.
Pages işleyici yönteminde veya MVC denetleyicisinde Razor belirli istekler için durum kodu sayfalarını devre dışı bırakmak için kullanın IStatusCodePagesFeature:
public void OnGet()
{
var statusCodePagesFeature =
HttpContext.Features.Get<IStatusCodePagesFeature>();
if (statusCodePagesFeature is not null)
{
statusCodePagesFeature.Enabled = false;
}
}
Özel durum işleme kodu
Özel durum işleme sayfalarındaki kod da özel durumlar oluşturabilir. Üretim hata sayfaları kapsamlı bir şekilde test edilmeli ve kendi özel durumlarının oluşmasını önlemek için ek özen gösterilmelidir.
Yanıt üst bilgileri
Yanıtın üst bilgileri gönderildikten sonra:
- Uygulama yanıtın durum kodunu değiştiremez.
- Özel durum sayfaları veya işleyicileri çalıştırılamaz. Yanıt tamamlanmalıdır veya bağlantı durdurulmalıdır.
Sunucu özel durum işleme
Bir uygulamadaki özel durum işleme mantığına ek olarak, HTTP sunucusu uygulaması bazı özel durumları işleyebilir. Sunucu yanıt üst bilgileri gönderilmeden önce bir özel durum yakalarsa, yanıt gövdesi olmadan bir 500 - Internal Server Error
yanıt gönderir. Yanıt üst bilgileri gönderildikten sonra sunucu bir özel durum yakalarsa, sunucu bağlantıyı kapatır. Uygulama tarafından işlenmemiş istekler sunucu tarafından işlenir. Sunucu isteği işlerken oluşan özel durumlar, sunucunun özel durum işlemesi tarafından işlenir. Uygulamanın özel hata sayfaları, özel durum işleme ara yazılımı ve filtreler bu davranışı etkilemez.
Özel durum işlemeyi başlatma
Yalnızca barındırma katmanı, uygulama başlatma sırasında gerçekleşen özel durumları işleyebilir. Konak, başlangıç hatalarını yakalamak ve ayrıntılı hataları yakalamak için yapılandırılabilir.
Barındırma katmanı, yakalanan başlatma hatası için yalnızca ana bilgisayar adresi/bağlantı noktası bağlaması sonrasında hata oluşması durumunda bir hata sayfası gösterebilir. Bağlama başarısız olursa:
- Barındırma katmanı kritik bir özel durumu günlüğe kaydeder.
- dotnet işlemi kilitleniyor.
- HTTP sunucusu olduğunda hiçbir hata sayfası görüntülenmez Kestrel.
IIS (veya Azure Uygulaması Hizmeti) veya IIS Express üzerinde çalışırken, işlem başlatılamıyorsa ASP.NET Çekirdek Modülü tarafından 502.5 - İşlem Hatası döndürülür. Daha fazla bilgi için bkz. Azure Uygulaması Hizmeti ve IIS'de ASP.NET Core sorunlarını giderme.
Veritabanı hata sayfası
Veritabanı geliştirici sayfası özel durum filtresi AddDatabaseDeveloperPageExceptionFilter , Entity Framework Core geçişleri kullanılarak çözümlenebilen veritabanıyla ilgili özel durumları yakalar. Bu özel durumlar oluştuğunda, sorunu çözmek için olası eylemlerin ayrıntılarıyla birlikte bir HTML yanıtı oluşturulur. Bu sayfa yalnızca Geliştirme ortamında etkinleştirilir. Aşağıdaki kod, Veritabanı geliştirici sayfası özel durum filtresini ekler:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddDatabaseDeveloperPageExceptionFilter();
builder.Services.AddRazorPages();
Özel durum filtreleri
MVC uygulamalarında özel durum filtreleri genel olarak veya denetleyici başına veya eylem temelinde yapılandırılabilir. Razor Sayfalar uygulamalarında, bunlar genel olarak veya sayfa modeli başına yapılandırılabilir. Bu filtreler, bir denetleyici eyleminin veya başka bir filtrenin yürütülmesi sırasında oluşan işlenmeyen özel durumları işler. Daha fazla bilgi için bkz . ASP.NET Core'daki filtreler.
Özel durum filtreleri, MVC eylemleri içinde oluşan özel durumları yakalamak için kullanışlıdır, ancak yerleşik özel durum işleme ara yazılımıUseExceptionHandler kadar esnek değildir. Hangi MVC eyleminin seçildiğine göre farklı hata işleme gerçekleştirmeniz gerekmediği sürece kullanmanızı UseExceptionHandler
öneririz.
Model durumu hataları
Model durumu hatalarını işleme hakkında bilgi için bkz . Model bağlama ve Model doğrulama.
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(IServiceCollection) ü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çermemesiAccept
dışı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
- ExceptionHandlerMiddleware: Özel işleyici tanımlanmadığında bir sorun ayrıntıları yanıtı oluşturur.
- StatusCodePagesMiddleware: Varsayılan olarak bir sorun ayrıntıları yanıtı oluşturur.
- DeveloperExceptionPageMiddleware: İstek HTTP üst bilgisi içermediğinde
Accept
text/html
geliştirme aşamasında bir sorun ayrıntıları yanıtı oluşturur.
Aşağıdaki kod, uygulamayı henüz gövde içeriği olmayan tüm HTTP istemcisi ve sunucu hata yanıtları için bir sorun ayrıntıları yanıtı oluşturacak şekilde yapılandırır:
builder.Services.AddProblemDetails();
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler();
app.UseHsts();
}
app.UseStatusCodePages();
Sonraki bölümde sorun ayrıntıları yanıt gövdesinin nasıl özelleştirileceği gösterilmektedir.
Sorun ayrıntılarını özelleştirme
öğesinin ProblemDetails
otomatik olarak oluşturulması, aşağıdaki seçeneklerden herhangi biri kullanılarak özelleştirilebilir:
ProblemDetailsOptions.CustomizeProblemDetails
komutunu kullanma- Özel kullanım
IProblemDetailsWriter
- ara yazılımda öğesini
IProblemDetailsService
çağırma
CustomizeProblemDetails
işlem
Oluşturulan sorun ayrıntıları kullanılarak CustomizeProblemDetailsözelleştirilebilir ve özelleştirmeler otomatik olarak oluşturulan tüm sorun ayrıntılarına uygulanır.
Ayarlamak için CustomizeProblemDetailsaşağıdaki kod kullanılırProblemDetailsOptions:
builder.Services.AddProblemDetails(options =>
options.CustomizeProblemDetails = ctx =>
ctx.ProblemDetails.Extensions.Add("nodeId", Environment.MachineName));
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler();
app.UseHsts();
}
app.UseStatusCodePages();
Örneğin, bir HTTP Status 400 Bad Request
uç nokta sonucu aşağıdaki sorun ayrıntıları yanıt gövdesini oluşturur:
{
"type": "https://tools.ietf.org/html/rfc9110#section-15.5.1",
"title": "Bad Request",
"status": 400,
"nodeId": "my-machine-name"
}
Töre IProblemDetailsWriter
Gelişmiş özelleştirmeler için bir IProblemDetailsWriter uygulama oluşturulabilir.
public class SampleProblemDetailsWriter : IProblemDetailsWriter
{
// Indicates that only responses with StatusCode == 400
// are handled by this writer. All others are
// handled by different registered writers if available.
public bool CanWrite(ProblemDetailsContext context)
=> context.HttpContext.Response.StatusCode == 400;
public ValueTask WriteAsync(ProblemDetailsContext context)
{
// Additional customizations.
// Write to the response.
var response = context.HttpContext.Response;
return new ValueTask(response.WriteAsJsonAsync(context.ProblemDetails));
}
}
Not: Özel IProblemDetailsWriter
kullanılırken, özel IProblemDetailsWriter
öğesinin , , AddControllersWithViewsAddControllersveya AddMvcçağrılmadan AddRazorPagesönce kaydedilmesi gerekir:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddTransient<IProblemDetailsWriter, SampleProblemDetailsWriter>();
var app = builder.Build();
// Middleware to handle writing problem details to the response.
app.Use(async (context, next) =>
{
await next(context);
var mathErrorFeature = context.Features.Get<MathErrorFeature>();
if (mathErrorFeature is not null)
{
if (context.RequestServices.GetService<IProblemDetailsWriter>() is
{ } problemDetailsService)
{
if (problemDetailsService.CanWrite(new ProblemDetailsContext() { HttpContext = context }))
{
(string Detail, string Type) details = mathErrorFeature.MathError switch
{
MathErrorType.DivisionByZeroError => ("Divison by zero is not defined.",
"https://en.wikipedia.org/wiki/Division_by_zero"),
_ => ("Negative or complex numbers are not valid input.",
"https://en.wikipedia.org/wiki/Square_root")
};
await problemDetailsService.WriteAsync(new ProblemDetailsContext
{
HttpContext = context,
ProblemDetails =
{
Title = "Bad Input",
Detail = details.Detail,
Type = details.Type
}
});
}
}
}
});
// /divide?numerator=2&denominator=4
app.MapGet("/divide", (HttpContext context, double numerator, double denominator) =>
{
if (denominator == 0)
{
var errorType = new MathErrorFeature
{
MathError = MathErrorType.DivisionByZeroError
};
context.Features.Set(errorType);
return Results.BadRequest();
}
return Results.Ok(numerator / denominator);
});
// /squareroot?radicand=16
app.MapGet("/squareroot", (HttpContext context, double radicand) =>
{
if (radicand < 0)
{
var errorType = new MathErrorFeature
{
MathError = MathErrorType.NegativeRadicandError
};
context.Features.Set(errorType);
return Results.BadRequest();
}
return Results.Ok(Math.Sqrt(radicand));
});
app.Run();
Ara Yazılımdan sorun ayrıntıları
ile CustomizeProblemDetails kullanmak ProblemDetailsOptions için alternatif bir yaklaşım, ara yazılımı ayarlamaktırProblemDetails. Bir sorun ayrıntıları yanıtı çağrılarak IProblemDetailsService.WriteAsync
yazılabilir:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllers();
builder.Services.AddProblemDetails();
var app = builder.Build();
app.UseHttpsRedirection();
app.UseStatusCodePages();
// Middleware to handle writing problem details to the response.
app.Use(async (context, next) =>
{
await next(context);
var mathErrorFeature = context.Features.Get<MathErrorFeature>();
if (mathErrorFeature is not null)
{
if (context.RequestServices.GetService<IProblemDetailsService>() is
{ } problemDetailsService)
{
(string Detail, string Type) details = mathErrorFeature.MathError switch
{
MathErrorType.DivisionByZeroError => ("Divison by zero is not defined.",
"https://en.wikipedia.org/wiki/Division_by_zero"),
_ => ("Negative or complex numbers are not valid input.",
"https://en.wikipedia.org/wiki/Square_root")
};
await problemDetailsService.WriteAsync(new ProblemDetailsContext
{
HttpContext = context,
ProblemDetails =
{
Title = "Bad Input",
Detail = details.Detail,
Type = details.Type
}
});
}
}
});
// /divide?numerator=2&denominator=4
app.MapGet("/divide", (HttpContext context, double numerator, double denominator) =>
{
if (denominator == 0)
{
var errorType = new MathErrorFeature { MathError =
MathErrorType.DivisionByZeroError };
context.Features.Set(errorType);
return Results.BadRequest();
}
return Results.Ok(numerator / denominator);
});
// /squareroot?radicand=16
app.MapGet("/squareroot", (HttpContext context, double radicand) =>
{
if (radicand < 0)
{
var errorType = new MathErrorFeature { MathError =
MathErrorType.NegativeRadicandError };
context.Features.Set(errorType);
return Results.BadRequest();
}
return Results.Ok(Math.Sqrt(radicand));
});
app.MapControllers();
app.Run();
Yukarıdaki kodda, en düşük API uç noktaları /divide
ve /squareroot
hata girişinde beklenen özel sorun yanıtını döndürür.
API denetleyicisi uç noktaları, özel sorun yanıtını değil hata girişinde varsayılan sorun yanıtını döndürür. API denetleyicisi yanıt akışına yazdığı için varsayılan sorun yanıtı döndürülür; hata durum kodları için sorun ayrıntıları, daha önce IProblemDetailsService.WriteAsync
çağrılır ve yanıt yeniden yazılmaz .
Aşağıdaki ValuesController
, yanıt akışına yazan ve bu nedenle özel sorun yanıtının döndürülmesini önleyen döndürür BadRequestResult.
[Route("api/[controller]/[action]")]
[ApiController]
public class ValuesController : ControllerBase
{
// /api/values/divide/1/2
[HttpGet("{Numerator}/{Denominator}")]
public IActionResult Divide(double Numerator, double Denominator)
{
if (Denominator == 0)
{
var errorType = new MathErrorFeature
{
MathError = MathErrorType.DivisionByZeroError
};
HttpContext.Features.Set(errorType);
return BadRequest();
}
return Ok(Numerator / Denominator);
}
// /api/values/squareroot/4
[HttpGet("{radicand}")]
public IActionResult Squareroot(double radicand)
{
if (radicand < 0)
{
var errorType = new MathErrorFeature
{
MathError = MathErrorType.NegativeRadicandError
};
HttpContext.Features.Set(errorType);
return BadRequest();
}
return Ok(Math.Sqrt(radicand));
}
}
Aşağıdaki Values3Controller
, beklenen özel sorun sonucunun döndürülmesi için döndürür ControllerBase.Problem
:
[Route("api/[controller]/[action]")]
[ApiController]
public class Values3Controller : ControllerBase
{
// /api/values3/divide/1/2
[HttpGet("{Numerator}/{Denominator}")]
public IActionResult Divide(double Numerator, double Denominator)
{
if (Denominator == 0)
{
var errorType = new MathErrorFeature
{
MathError = MathErrorType.DivisionByZeroError
};
HttpContext.Features.Set(errorType);
return Problem(
title: "Bad Input",
detail: "Divison by zero is not defined.",
type: "https://en.wikipedia.org/wiki/Division_by_zero",
statusCode: StatusCodes.Status400BadRequest
);
}
return Ok(Numerator / Denominator);
}
// /api/values3/squareroot/4
[HttpGet("{radicand}")]
public IActionResult Squareroot(double radicand)
{
if (radicand < 0)
{
var errorType = new MathErrorFeature
{
MathError = MathErrorType.NegativeRadicandError
};
HttpContext.Features.Set(errorType);
return Problem(
title: "Bad Input",
detail: "Negative or complex numbers are not valid input.",
type: "https://en.wikipedia.org/wiki/Square_root",
statusCode: StatusCodes.Status400BadRequest
);
}
return Ok(Math.Sqrt(radicand));
}
}
Özel durumlar için ProblemDetails yükü oluşturma
Aşağıdaki uygulamayı göz önünde bulundurun:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllers();
builder.Services.AddProblemDetails();
var app = builder.Build();
app.UseExceptionHandler();
app.UseStatusCodePages();
if (app.Environment.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.MapControllers();
app.Run();
Geliştirme dışı ortamlarda, bir özel durum oluştuğunda, istemciye döndürülen standart bir ProblemDetails yanıtı aşağıdadır:
{
"type":"https://tools.ietf.org/html/rfc7231#section-6.6.1",
"title":"An error occurred while processing your request.",
"status":500,"traceId":"00-b644<snip>-00"
}
Çoğu uygulama için, özel durumlar için gereken tek şey yukarıdaki koddur. Ancak aşağıdaki bölümde daha ayrıntılı sorun yanıtlarının nasıl alınıyor olduğu gösterilmektedir.
Özel özel durum işleyici sayfasının alternatifi, öğesine UseExceptionHandlerbir lambda sağlamaktır. Lambda kullanmak hataya erişim sağlar ve ile IProblemDetailsService.WriteAsync
bir sorun ayrıntıları yanıtı yazar:
using Microsoft.AspNetCore.Diagnostics;
using static System.Net.Mime.MediaTypeNames;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllers();
builder.Services.AddProblemDetails();
var app = builder.Build();
app.UseExceptionHandler();
app.UseStatusCodePages();
if (app.Environment.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler(exceptionHandlerApp =>
{
exceptionHandlerApp.Run(async context =>
{
context.Response.StatusCode = StatusCodes.Status500InternalServerError;
context.Response.ContentType = Text.Plain;
var title = "Bad Input";
var detail = "Invalid input";
var type = "https://errors.example.com/badInput";
if (context.RequestServices.GetService<IProblemDetailsService>() is
{ } problemDetailsService)
{
var exceptionHandlerFeature =
context.Features.Get<IExceptionHandlerFeature>();
var exceptionType = exceptionHandlerFeature?.Error;
if (exceptionType != null &&
exceptionType.Message.Contains("infinity"))
{
title = "Argument exception";
detail = "Invalid input";
type = "https://errors.example.com/argumentException";
}
await problemDetailsService.WriteAsync(new ProblemDetailsContext
{
HttpContext = context,
ProblemDetails =
{
Title = title,
Detail = detail,
Type = type
}
});
}
});
});
}
app.MapControllers();
app.Run();
Uyarı
Hassas hata bilgilerini istemcilere sunma. Hata sunma bir güvenlik riskidir.
Sorun ayrıntıları oluşturmak için alternatif bir yaklaşım, özel durumları ve istemci hatalarını sorun ayrıntılarıyla eşlemek için kullanılabilecek üçüncü taraf NuGet paketini Hellang.Middleware.ProblemDetails kullanmaktır.
Ek kaynaklar
Tarafından Tom Dykstra
Bu makalede, ASP.NET Core web uygulamalarında hataları işlemeye yönelik yaygın yaklaşımlar ele alınıyor. Bkz . Web API'leri için ASP.NET Core denetleyici tabanlı web API'lerindeki hataları işleme.
Geliştirici özel durum sayfası
Geliştirici Özel Durum Sayfası, işlenmeyen istek özel durumları hakkında ayrıntılı bilgiler görüntüler. ASP.NET Core uygulamaları, her ikisi de aşağıdaki durumlarda varsayılan olarak geliştirici özel durum sayfasını etkinleştirir:
- Geliştirme ortamında çalıştırılıyor.
- Geçerli şablonlarla, yani WebApplication.CreateBuilder kullanılarak oluşturulan uygulama. kullanılarak oluşturulan uygulamalar,
WebHost.CreateDefaultBuilder
içindeConfigure
arayarakapp.UseDeveloperExceptionPage
geliştirici özel durum sayfasını etkinleştirmelidir.
Geliştirici özel durum sayfası ara yazılım işlem hattında erken çalıştırılır, böylece izleyen ara yazılımda işlenmeyen özel durumları yakalayabilir.
Uygulama Üretim ortamında çalıştırıldığında ayrıntılı özel durum bilgileri genel olarak görüntülenmemelidir. Ortamları yapılandırma hakkında daha fazla bilgi için bkz . ASP.NET Core'da birden çok ortam kullanma.
Geliştirici Özel Durum Sayfası, özel durum ve istek hakkında aşağıdaki bilgileri içerebilir:
- Yığın izleme
- Varsa sorgu dizesi parametreleri
- Varsa tanımlama bilgileri
- Üst Bilgiler
Geliştirici Özel Durum Sayfası'nın herhangi bir bilgi sağlaması garanti değildir. Tam hata bilgileri için Günlüğe Kaydetme özelliğini kullanın.
Özel durum işleyici sayfası
Üretim ortamı için özel bir hata işleme sayfası yapılandırmak için öğesini çağırınUseExceptionHandler. Ara yazılımı işleyen bu özel durum:
- İşlenmeyen özel durumları yakalar ve günlüğe kaydeder.
- Belirtilen yolu kullanarak isteği alternatif bir işlem hattında yeniden yürütür. Yanıt başlatıldıysa istek yeniden yürütülemez. Şablon tarafından oluşturulan kod, yolu kullanarak isteği yeniden yürütür
/Error
.
Uyarı
Alternatif işlem hattı kendi özel durumu oluşturursa, Özel Durum İşleme Ara Yazılımı özgün özel durumu yeniden oluşturur.
Aşağıdaki örnekte, UseExceptionHandler Geliştirme dışı ortamlarda özel durum işleme ara yazılımını ekler:
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
Sayfalar uygulama şablonu, Razor Sayfalar klasöründe bir Hata sayfası (.cshtml
) ve PageModel sınıf (ErrorModel
) sağlar. Bir MVC uygulaması için proje şablonu, denetleyici için Home bir Error
eylem yöntemi ve Hata görünümü içerir.
Özel durum işleme ara yazılımı özgün HTTP yöntemini kullanarak isteği yeniden yürütür. Hata işleyicisi uç noktası belirli bir HTTP yöntemleri kümesiyle sınırlıysa, yalnızca bu HTTP yöntemleri için çalışır. Örneğin, özniteliğini kullanan [HttpGet]
bir MVC denetleyicisi eylemi yalnızca GET istekleri için çalıştırılır. Tüm isteklerin özel hata işleme sayfasına ulaştığından emin olmak için bunları belirli bir HTTP yöntemleri kümesiyle kısıtlamayın.
Özel durumları özgün HTTP yöntemine göre farklı şekilde işlemek için:
- Sayfalar için Razor birden çok işleyici yöntemi oluşturun. Örneğin, GET özel durumlarını işlemek için kullanın
OnGet
ve POST özel durumlarını işlemek için kullanınOnPost
. - MVC için, birden çok eyleme HTTP fiili öznitelikleri uygulayın. Örneğin, GET özel durumlarını işlemek için kullanın
[HttpGet]
ve POST özel durumlarını işlemek için kullanın[HttpPost]
.
Kimliği doğrulanmamış kullanıcıların özel hata işleme sayfasını görüntülemesine izin vermek için anonim erişimi desteklediğinden emin olun.
Özel duruma erişme
Hata işleyicisinde özel duruma ve özgün istek yoluna erişmek için kullanın IExceptionHandlerPathFeature . Aşağıdaki örnek, oluşturulan özel durum hakkında daha fazla bilgi almak için kullanır IExceptionHandlerPathFeature
:
[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
[IgnoreAntiforgeryToken]
public class ErrorModel : PageModel
{
public string? RequestId { get; set; }
public bool ShowRequestId => !string.IsNullOrEmpty(RequestId);
public string? ExceptionMessage { get; set; }
public void OnGet()
{
RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier;
var exceptionHandlerPathFeature =
HttpContext.Features.Get<IExceptionHandlerPathFeature>();
if (exceptionHandlerPathFeature?.Error is FileNotFoundException)
{
ExceptionMessage = "The file was not found.";
}
if (exceptionHandlerPathFeature?.Path == "/")
{
ExceptionMessage ??= string.Empty;
ExceptionMessage += " Page: Home.";
}
}
}
Uyarı
Hassas hata bilgilerini istemcilere sunma. Hata sunma bir güvenlik riskidir.
Özel durum işleyici lambda
Özel özel durum işleyici sayfasının alternatifi, öğesine UseExceptionHandlerbir lambda sağlamaktır. Lambda kullanmak, yanıtı döndürmeden önce hataya erişim sağlar.
Aşağıdaki kod özel durum işleme için bir lambda kullanır:
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler(exceptionHandlerApp =>
{
exceptionHandlerApp.Run(async context =>
{
context.Response.StatusCode = StatusCodes.Status500InternalServerError;
// using static System.Net.Mime.MediaTypeNames;
context.Response.ContentType = Text.Plain;
await context.Response.WriteAsync("An exception was thrown.");
var exceptionHandlerPathFeature =
context.Features.Get<IExceptionHandlerPathFeature>();
if (exceptionHandlerPathFeature?.Error is FileNotFoundException)
{
await context.Response.WriteAsync(" The file was not found.");
}
if (exceptionHandlerPathFeature?.Path == "/")
{
await context.Response.WriteAsync(" Page: Home.");
}
});
});
app.UseHsts();
}
Uyarı
Hassas hata bilgilerini istemcilere sunma. Hata sunma bir güvenlik riskidir.
UseStatusCodePages
Varsayılan olarak, ASP.NET Core uygulaması HTTP hata durum kodları için 404 - Bulunamadı gibi bir durum kodu sayfası sağlamaz. Uygulama gövdesi olmayan bir HTTP 400-599 hata durum kodu ayarladığında, durum kodunu ve boş bir yanıt gövdesini döndürür. Yaygın hata durum kodları için varsayılan yalnızca metin işleyicilerini etkinleştirmek için çağrısında UseStatusCodePages kullanın Program.cs
:
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseStatusCodePages();
İstek işleme ara yazılımından önce çağırın UseStatusCodePages
. Örneğin, Statik Dosya Ara Yazılımı ve Uç Noktalar Ara Yazılımı'nın önünde çağırın UseStatusCodePages
.
Kullanılmadığında UseStatusCodePages
, uç nokta olmadan URL'ye gitmek, uç noktanın bulunamadığını belirten tarayıcıya bağlı bir hata iletisi döndürür. Çağrıldığında UseStatusCodePages
, tarayıcı aşağıdaki yanıtı döndürür:
Status Code: 404; Not Found
UseStatusCodePages
genellikle üretimde kullanılmaz çünkü kullanıcılar için yararlı olmayan bir ileti döndürür.
Not
Durum kodu sayfaları ara yazılımı özel durumları yakalamaz. Özel hata işleme sayfası sağlamak için özel durum işleyici sayfasını kullanın.
Biçim dizesi ile UseStatusCodePages
Yanıt içerik türünü ve metnini özelleştirmek için, bir içerik türü ve biçim dizesi alan öğesinin aşırı yüklemesini UseStatusCodePages kullanın:
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
// using static System.Net.Mime.MediaTypeNames;
app.UseStatusCodePages(Text.Plain, "Status Code Page: {0}");
Yukarıdaki kodda, {0}
hata kodu için bir yer tutucudur.
UseStatusCodePages
kullanıcılar için yararlı olmayan bir ileti döndürdüğü için, biçim dizesi genellikle üretimde kullanılmaz.
Lambda ile UseStatusCodePages
Özel hata işleme ve yanıt yazma kodu belirtmek için bir lambda ifadesi alan öğesinin aşırı yüklemesini UseStatusCodePages kullanın:
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseStatusCodePages(async statusCodeContext =>
{
// using static System.Net.Mime.MediaTypeNames;
statusCodeContext.HttpContext.Response.ContentType = Text.Plain;
await statusCodeContext.HttpContext.Response.WriteAsync(
$"Status Code Page: {statusCodeContext.HttpContext.Response.StatusCode}");
});
UseStatusCodePages
lambda ile genellikle üretimde kullanılmaz çünkü kullanıcılar için yararlı olmayan bir ileti döndürür.
UseStatusCodePagesWithRedirects
UseStatusCodePagesWithRedirects Uzantı yöntemi:
- İstemciye bir 302 - Bulundu durum kodu gönderir.
- İstemciyi URL şablonunda sağlanan hata işleme uç noktasına yönlendirir. Hata işleme uç noktası genellikle hata bilgilerini görüntüler ve HTTP 200 döndürür.
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseStatusCodePagesWithRedirects("/StatusCode/{0}");
URL şablonu, önceki kodda gösterildiği gibi durum kodu için bir {0}
yer tutucu içerebilir. URL şablonu (tilde) ile ~
başlıyorsa, ~
yerine uygulamanın PathBase
olur. Uygulamada bir uç nokta belirtirken, uç nokta için bir MVC görünümü veya Razor sayfası oluşturun.
Bu yöntem genellikle uygulama şu durumlarda kullanılır:
- genellikle farklı bir uygulamanın hatayı işlediği durumlarda istemciyi farklı bir uç noktaya yönlendirmelidir. Web uygulamaları için istemcinin tarayıcı adres çubuğu yeniden yönlendirilen uç noktayı yansıtır.
- İlk yeniden yönlendirme yanıtıyla özgün durum kodunu korumamalı ve döndürmemelidir.
UseStatusCodePagesWithReExecute
UseStatusCodePagesWithReExecute Uzantı yöntemi:
- İstemciye özgün durum kodunu döndürür.
- Alternatif bir yol kullanarak istek işlem hattını yeniden yürüterek yanıt gövdesini oluşturur.
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseStatusCodePagesWithReExecute("/StatusCode/{0}");
Uygulama içinde bir uç nokta belirtilirse, uç nokta için bir MVC görünümü veya Razor sayfası oluşturun.
Bu yöntem genellikle uygulamanın aşağıdakileri yapması gerektiğinde kullanılır:
- İsteği farklı bir uç noktaya yeniden yönlendirmeden işleyin. Web uygulamaları için istemcinin tarayıcı adres çubuğu başlangıçta istenen uç noktayı yansıtır.
- Yanıtla birlikte özgün durum kodunu koruyun ve döndürin.
URL şablonu ile /
başlamalıdır ve durum kodu için bir yer tutucu {0}
içerebilir. Durum kodunu sorgu dizesi parametresi olarak geçirmek için içine ikinci bir bağımsız değişken UseStatusCodePagesWithReExecute
geçirin. Örneğin:
app.UseStatusCodePagesWithReExecute("/StatusCode", "?statusCode={0}");
Hatayı işleyen uç nokta, aşağıdaki örnekte gösterildiği gibi hatayı oluşturan özgün URL'yi alabilir:
[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
public class StatusCodeModel : PageModel
{
public int OriginalStatusCode { get; set; }
public string? OriginalPathAndQuery { get; set; }
public void OnGet(int statusCode)
{
OriginalStatusCode = statusCode;
var statusCodeReExecuteFeature =
HttpContext.Features.Get<IStatusCodeReExecuteFeature>();
if (statusCodeReExecuteFeature is not null)
{
OriginalPathAndQuery = string.Join(
statusCodeReExecuteFeature.OriginalPathBase,
statusCodeReExecuteFeature.OriginalPath,
statusCodeReExecuteFeature.OriginalQueryString);
}
}
}
Durum kodu sayfalarını devre dışı bırakma
MVC denetleyicisinin veya eylem yönteminin durum kodu sayfalarını devre dışı bırakmak için [SkipStatusCodePages] özniteliğini kullanın.
Pages işleyici yönteminde veya MVC denetleyicisinde Razor belirli istekler için durum kodu sayfalarını devre dışı bırakmak için kullanın IStatusCodePagesFeature:
public void OnGet()
{
var statusCodePagesFeature =
HttpContext.Features.Get<IStatusCodePagesFeature>();
if (statusCodePagesFeature is not null)
{
statusCodePagesFeature.Enabled = false;
}
}
Özel durum işleme kodu
Özel durum işleme sayfalarındaki kod da özel durumlar oluşturabilir. Üretim hata sayfaları kapsamlı bir şekilde test edilmeli ve kendi özel durumlarının oluşmasını önlemek için ek özen gösterilmelidir.
Yanıt üst bilgileri
Yanıtın üst bilgileri gönderildikten sonra:
- Uygulama yanıtın durum kodunu değiştiremez.
- Özel durum sayfaları veya işleyicileri çalıştırılamaz. Yanıt tamamlanmalıdır veya bağlantı durdurulmalıdır.
Sunucu özel durum işleme
Bir uygulamadaki özel durum işleme mantığına ek olarak, HTTP sunucusu uygulaması bazı özel durumları işleyebilir. Sunucu yanıt üst bilgileri gönderilmeden önce bir özel durum yakalarsa, yanıt gövdesi olmadan bir 500 - Internal Server Error
yanıt gönderir. Yanıt üst bilgileri gönderildikten sonra sunucu bir özel durum yakalarsa, sunucu bağlantıyı kapatır. Uygulama tarafından işlenmemiş istekler sunucu tarafından işlenir. Sunucu isteği işlerken oluşan özel durumlar, sunucunun özel durum işlemesi tarafından işlenir. Uygulamanın özel hata sayfaları, özel durum işleme ara yazılımı ve filtreler bu davranışı etkilemez.
Özel durum işlemeyi başlatma
Yalnızca barındırma katmanı, uygulama başlatma sırasında gerçekleşen özel durumları işleyebilir. Konak, başlangıç hatalarını yakalamak ve ayrıntılı hataları yakalamak için yapılandırılabilir.
Barındırma katmanı, yakalanan başlatma hatası için yalnızca ana bilgisayar adresi/bağlantı noktası bağlaması sonrasında hata oluşması durumunda bir hata sayfası gösterebilir. Bağlama başarısız olursa:
- Barındırma katmanı kritik bir özel durumu günlüğe kaydeder.
- dotnet işlemi kilitleniyor.
- HTTP sunucusu olduğunda hiçbir hata sayfası görüntülenmez Kestrel.
IIS (veya Azure Uygulaması Hizmeti) veya IIS Express üzerinde çalışırken, işlem başlatılamıyorsa ASP.NET Çekirdek Modülü tarafından 502.5 - İşlem Hatası döndürülür. Daha fazla bilgi için bkz. Azure Uygulaması Hizmeti ve IIS'de ASP.NET Core sorunlarını giderme.
Veritabanı hata sayfası
Veritabanı geliştirici sayfası özel durum filtresi AddDatabaseDeveloperPageExceptionFilter , Entity Framework Core geçişleri kullanılarak çözümlenebilen veritabanıyla ilgili özel durumları yakalar. Bu özel durumlar oluştuğunda, sorunu çözmek için olası eylemlerin ayrıntılarıyla birlikte bir HTML yanıtı oluşturulur. Bu sayfa yalnızca Geliştirme ortamında etkinleştirilir. Aşağıdaki kod, Veritabanı geliştirici sayfası özel durum filtresini ekler:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddDatabaseDeveloperPageExceptionFilter();
builder.Services.AddRazorPages();
Özel durum filtreleri
MVC uygulamalarında özel durum filtreleri genel olarak veya denetleyici başına veya eylem temelinde yapılandırılabilir. Razor Sayfalar uygulamalarında, bunlar genel olarak veya sayfa modeli başına yapılandırılabilir. Bu filtreler, bir denetleyici eyleminin veya başka bir filtrenin yürütülmesi sırasında oluşan işlenmeyen özel durumları işler. Daha fazla bilgi için bkz . ASP.NET Core'daki filtreler.
Özel durum filtreleri, MVC eylemleri içinde oluşan özel durumları yakalamak için kullanışlıdır, ancak yerleşik özel durum işleme ara yazılımıUseExceptionHandler kadar esnek değildir. Hangi MVC eyleminin seçildiğine göre farklı hata işleme gerçekleştirmeniz gerekmediği sürece kullanmanızı UseExceptionHandler
öneririz.
Model durumu hataları
Model durumu hatalarını işleme hakkında bilgi için bkz . Model bağlama ve Model doğrulama.
Ek kaynaklar
Kirk Larkin, Tom Dykstra ve Steve Smith tarafından
Bu makalede, ASP.NET Core web uygulamalarında hataları işlemeye yönelik yaygın yaklaşımlar ele alınıyor. Bkz . Web API'leri için ASP.NET Core denetleyici tabanlı web API'lerindeki hataları işleme.
Örnek kodu görüntüleyin veya indirme. (nasıl indirilir.) F12 tarayıcı geliştirici araçlarının ağ sekmesi, örnek uygulamayı test ederken kullanışlıdır.
Geliştirici Özel Durum Sayfası
Geliştirici Özel Durum Sayfası, işlenmeyen istek özel durumları hakkında ayrıntılı bilgiler görüntüler. ASP.NET Core şablonları aşağıdaki kodu oluşturur:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapRazorPages();
});
}
Yukarıdaki vurgulanan kod, uygulama Geliştirme ortamında çalışırken geliştirici özel durum sayfasını etkinleştirir.
Şablonlar ara yazılım işlem hattının erken aşamalarına yerleştirerek UseDeveloperExceptionPage aşağıdaki ara yazılımda oluşan işlenmeyen özel durumları yakalayabilmesini sağlar.
Yukarıdaki kod, Geliştirici Özel Durum Sayfası'nı yalnızca uygulama Geliştirme ortamında çalıştığında etkinleştirir. Uygulama Üretim ortamında çalıştırıldığında ayrıntılı özel durum bilgileri genel olarak görüntülenmemelidir. Ortamları yapılandırma hakkında daha fazla bilgi için bkz . ASP.NET Core'da birden çok ortam kullanma.
Geliştirici Özel Durum Sayfası, özel durum ve istek hakkında aşağıdaki bilgileri içerebilir:
- Yığın izleme
- Varsa sorgu dizesi parametreleri
- Varsa tanımlama bilgileri
- Üst Bilgiler
Geliştirici Özel Durum Sayfası'nın herhangi bir bilgi sağlaması garanti değildir. Tam hata bilgileri için Günlüğe Kaydetme özelliğini kullanın.
Özel durum işleyici sayfası
Üretim ortamı için özel bir hata işleme sayfası yapılandırmak için öğesini çağırınUseExceptionHandler. Ara yazılımı işleyen bu özel durum:
- İşlenmeyen özel durumları yakalar ve günlüğe kaydeder.
- Belirtilen yolu kullanarak isteği alternatif bir işlem hattında yeniden yürütür. Yanıt başlatıldıysa istek yeniden yürütülemez. Şablon tarafından oluşturulan kod, yolu kullanarak isteği yeniden yürütür
/Error
.
Uyarı
Alternatif işlem hattı kendi özel durumu oluşturursa, Özel Durum İşleme Ara Yazılımı özgün özel durumu yeniden oluşturur.
Aşağıdaki örnekte, UseExceptionHandler Geliştirme dışı ortamlarda özel durum işleme ara yazılımını ekler:
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
Sayfalar uygulama şablonu, Razor Sayfalar klasöründe bir Hata sayfası (.cshtml
) ve PageModel sınıf (ErrorModel
) sağlar. Bir MVC uygulaması için proje şablonu, denetleyici için Home bir Error
eylem yöntemi ve Hata görünümü içerir.
Özel durum işleme ara yazılımı özgün HTTP yöntemini kullanarak isteği yeniden yürütür. Hata işleyicisi uç noktası belirli bir HTTP yöntemleri kümesiyle sınırlıysa, yalnızca bu HTTP yöntemleri için çalışır. Örneğin, özniteliğini kullanan [HttpGet]
bir MVC denetleyicisi eylemi yalnızca GET istekleri için çalıştırılır. Tüm isteklerin özel hata işleme sayfasına ulaştığından emin olmak için bunları belirli bir HTTP yöntemleri kümesiyle kısıtlamayın.
Özel durumları özgün HTTP yöntemine göre farklı şekilde işlemek için:
- Sayfalar için Razor birden çok işleyici yöntemi oluşturun. Örneğin, GET özel durumlarını işlemek için kullanın
OnGet
ve POST özel durumlarını işlemek için kullanınOnPost
. - MVC için, birden çok eyleme HTTP fiili öznitelikleri uygulayın. Örneğin, GET özel durumlarını işlemek için kullanın
[HttpGet]
ve POST özel durumlarını işlemek için kullanın[HttpPost]
.
Kimliği doğrulanmamış kullanıcıların özel hata işleme sayfasını görüntülemesine izin vermek için anonim erişimi desteklediğinden emin olun.
Özel duruma erişme
Hata işleyicisinde özel duruma ve özgün istek yoluna erişmek için kullanın IExceptionHandlerPathFeature . Aşağıdaki kod, ASP.NET Core şablonları tarafından oluşturulan varsayılan Pages/Error.cshtml.cs
değere eklenirExceptionMessage
:
[ResponseCache(Duration=0, Location=ResponseCacheLocation.None, NoStore=true)]
[IgnoreAntiforgeryToken]
public class ErrorModel : PageModel
{
public string RequestId { get; set; }
public bool ShowRequestId => !string.IsNullOrEmpty(RequestId);
public string ExceptionMessage { get; set; }
private readonly ILogger<ErrorModel> _logger;
public ErrorModel(ILogger<ErrorModel> logger)
{
_logger = logger;
}
public void OnGet()
{
RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier;
var exceptionHandlerPathFeature =
HttpContext.Features.Get<IExceptionHandlerPathFeature>();
if (exceptionHandlerPathFeature?.Error is FileNotFoundException)
{
ExceptionMessage = "File error thrown";
_logger.LogError(ExceptionMessage);
}
if (exceptionHandlerPathFeature?.Path == "/index")
{
ExceptionMessage += " from home page";
}
}
}
Uyarı
Hassas hata bilgilerini istemcilere sunma. Hata sunma bir güvenlik riskidir.
Örnek uygulamada özel durumu test etmek için:
- Ortamı üretim olarak ayarlayın.
- içindeki
Program.cs
açıklamalarınıwebBuilder.UseStartup<Startup>();
kaldırın. - Sayfada Özel durum tetikle'yi home seçin.
Özel durum işleyici lambda
Özel özel durum işleyici sayfasının alternatifi, öğesine UseExceptionHandlerbir lambda sağlamaktır. Lambda kullanmak, yanıtı döndürmeden önce hataya erişim sağlar.
Aşağıdaki kod özel durum işleme için bir lambda kullanır:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler(errorApp =>
{
errorApp.Run(async context =>
{
context.Response.StatusCode = (int) HttpStatusCode.InternalServerError;;
context.Response.ContentType = "text/html";
await context.Response.WriteAsync("<html lang=\"en\"><body>\r\n");
await context.Response.WriteAsync("ERROR!<br><br>\r\n");
var exceptionHandlerPathFeature =
context.Features.Get<IExceptionHandlerPathFeature>();
if (exceptionHandlerPathFeature?.Error is FileNotFoundException)
{
await context.Response.WriteAsync(
"File error thrown!<br><br>\r\n");
}
await context.Response.WriteAsync(
"<a href=\"/\">Home</a><br>\r\n");
await context.Response.WriteAsync("</body></html>\r\n");
await context.Response.WriteAsync(new string(' ', 512));
});
});
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapRazorPages();
});
}
Uyarı
İstemcilerden veya istemcilere hassas hata bilgileri sağlamayınIExceptionHandlerFeature.IExceptionHandlerPathFeature Hata sunma bir güvenlik riskidir.
Örnek uygulamada lambda işleme özel durumunu test etmek için:
- Ortamı üretim olarak ayarlayın.
- içindeki
Program.cs
açıklamalarınıwebBuilder.UseStartup<StartupLambda>();
kaldırın. - Sayfada Özel durum tetikle'yi home seçin.
UseStatusCodePages
Varsayılan olarak, ASP.NET Core uygulaması HTTP hata durum kodları için 404 - Bulunamadı gibi bir durum kodu sayfası sağlamaz. Uygulama gövdesi olmayan bir HTTP 400-599 hata durum kodu ayarladığında, durum kodunu ve boş bir yanıt gövdesini döndürür. Durum kodu sayfaları sağlamak için durum kodu sayfaları ara yazılımını kullanın. Yaygın hata durum kodları için varsayılan yalnızca metin işleyicilerini etkinleştirmek için yöntemini çağırın UseStatusCodePages Startup.Configure
:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseStatusCodePages();
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapRazorPages();
});
}
İstek işleme ara yazılımından önce çağırın UseStatusCodePages
. Örneğin, Statik Dosya Ara Yazılımı ve Uç Noktalar Ara Yazılımı'nın önünde çağırın UseStatusCodePages
.
Kullanılmadığında UseStatusCodePages
, uç nokta olmadan URL'ye gitmek, uç noktanın bulunamadığını belirten tarayıcıya bağlı bir hata iletisi döndürür. Örneğin, adresine gitmek.Home/Privacy2
Çağrıldığında UseStatusCodePages
tarayıcı şunu döndürür:
Status Code: 404; Not Found
UseStatusCodePages
genellikle üretimde kullanılmaz çünkü kullanıcılar için yararlı olmayan bir ileti döndürür.
Örnek uygulamada test UseStatusCodePages
etmek için:
- Ortamı üretim olarak ayarlayın.
- içindeki
Program.cs
açıklamalarınıwebBuilder.UseStartup<StartupUseStatusCodePages>();
kaldırın. - Sayfadaki home bağlantıları home seçin.
Not
Durum kodu sayfaları ara yazılımı özel durumları yakalamaz. Özel hata işleme sayfası sağlamak için özel durum işleyici sayfasını kullanın.
Biçim dizesi ile UseStatusCodePages
Yanıt içerik türünü ve metnini özelleştirmek için, bir içerik türü ve biçim dizesi alan öğesinin aşırı yüklemesini UseStatusCodePages kullanın:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseStatusCodePages(
"text/plain", "Status code page, status code: {0}");
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapRazorPages();
});
}
Yukarıdaki kodda, {0}
hata kodu için bir yer tutucudur.
UseStatusCodePages
kullanıcılar için yararlı olmayan bir ileti döndürdüğü için, biçim dizesi genellikle üretimde kullanılmaz.
Örnek uygulamada test UseStatusCodePages
etmek için içindeki açıklamalarını webBuilder.UseStartup<StartupFormat>();
Program.cs
kaldırın.
Lambda ile UseStatusCodePages
Özel hata işleme ve yanıt yazma kodu belirtmek için bir lambda ifadesi alan öğesinin aşırı yüklemesini UseStatusCodePages kullanın:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseStatusCodePages(async context =>
{
context.HttpContext.Response.ContentType = "text/plain";
await context.HttpContext.Response.WriteAsync(
"Status code page, status code: " +
context.HttpContext.Response.StatusCode);
});
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapRazorPages();
});
}
UseStatusCodePages
lambda ile genellikle üretimde kullanılmaz çünkü kullanıcılar için yararlı olmayan bir ileti döndürür.
Örnek uygulamada test UseStatusCodePages
etmek için içindeki açıklamalarını webBuilder.UseStartup<StartupStatusLambda>();
Program.cs
kaldırın.
UseStatusCodePagesWithRedirects
UseStatusCodePagesWithRedirects Uzantı yöntemi:
- İstemciye bir 302 - Bulundu durum kodu gönderir.
- İstemciyi URL şablonunda sağlanan hata işleme uç noktasına yönlendirir. Hata işleme uç noktası genellikle hata bilgilerini görüntüler ve HTTP 200 döndürür.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseStatusCodePagesWithRedirects("/MyStatusCode?code={0}");
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapRazorPages();
});
}
URL şablonu, önceki kodda gösterildiği gibi durum kodu için bir {0}
yer tutucu içerebilir. URL şablonu (tilde) ile ~
başlıyorsa, ~
yerine uygulamanın PathBase
olur. Uygulamada bir uç nokta belirtirken, uç nokta için bir MVC görünümü veya Razor sayfası oluşturun. Razor Sayfalar örneği için örnek uygulamadaki Pages/MyStatusCode.cshtml dosyasına bakın.
Bu yöntem genellikle uygulama şu durumlarda kullanılır:
- genellikle farklı bir uygulamanın hatayı işlediği durumlarda istemciyi farklı bir uç noktaya yönlendirmelidir. Web uygulamaları için istemcinin tarayıcı adres çubuğu yeniden yönlendirilen uç noktayı yansıtır.
- İlk yeniden yönlendirme yanıtıyla özgün durum kodunu korumamalı ve döndürmemelidir.
Örnek uygulamada test UseStatusCodePages
etmek için içindeki açıklamalarını webBuilder.UseStartup<StartupSCredirect>();
Program.cs
kaldırın.
UseStatusCodePagesWithReExecute
UseStatusCodePagesWithReExecute Uzantı yöntemi:
- İstemciye özgün durum kodunu döndürür.
- Alternatif bir yol kullanarak istek işlem hattını yeniden yürüterek yanıt gövdesini oluşturur.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseStatusCodePagesWithReExecute("/MyStatusCode2", "?code={0}");
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapRazorPages();
});
}
Uygulama içinde bir uç nokta belirtilirse, uç nokta için bir MVC görünümü veya Razor sayfası oluşturun. İsteğin durum sayfasına yeniden yönlendirilmesi için önce UseRouting
yerleştirildiğinden emin olunUseStatusCodePagesWithReExecute
. Razor Sayfalar örneği için örnek uygulamadaki Pages/MyStatusCode2.cshtml dosyasına bakın.
Bu yöntem genellikle uygulamanın aşağıdakileri yapması gerektiğinde kullanılır:
- İsteği farklı bir uç noktaya yeniden yönlendirmeden işleyin. Web uygulamaları için istemcinin tarayıcı adres çubuğu başlangıçta istenen uç noktayı yansıtır.
- Yanıtla birlikte özgün durum kodunu koruyun ve döndürin.
URL ve sorgu dizesi şablonları durum kodu için bir yer tutucu {0}
içerebilir. URL şablonu ile /
başlamalıdır.
Hatayı işleyen uç nokta, aşağıdaki örnekte gösterildiği gibi hatayı oluşturan özgün URL'yi alabilir:
[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
public class MyStatusCode2Model : PageModel
{
public string RequestId { get; set; }
public bool ShowRequestId => !string.IsNullOrEmpty(RequestId);
public string ErrorStatusCode { get; set; }
public string OriginalURL { get; set; }
public bool ShowOriginalURL => !string.IsNullOrEmpty(OriginalURL);
public void OnGet(string code)
{
RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier;
ErrorStatusCode = code;
var statusCodeReExecuteFeature = HttpContext.Features.Get<
IStatusCodeReExecuteFeature>();
if (statusCodeReExecuteFeature != null)
{
OriginalURL =
statusCodeReExecuteFeature.OriginalPathBase
+ statusCodeReExecuteFeature.OriginalPath
+ statusCodeReExecuteFeature.OriginalQueryString;
}
}
}
Razor Sayfalar örneği için örnek uygulamadaki Pages/MyStatusCode2.cshtml dosyasına bakın.
Örnek uygulamada test UseStatusCodePages
etmek için içindeki açıklamalarını webBuilder.UseStartup<StartupSCreX>();
Program.cs
kaldırın.
Durum kodu sayfalarını devre dışı bırakma
MVC denetleyicisinin veya eylem yönteminin durum kodu sayfalarını devre dışı bırakmak için [SkipStatusCodePages] özniteliğini kullanın.
Pages işleyici yönteminde veya MVC denetleyicisinde Razor belirli istekler için durum kodu sayfalarını devre dışı bırakmak için kullanın IStatusCodePagesFeature:
public void OnGet()
{
// using Microsoft.AspNetCore.Diagnostics;
var statusCodePagesFeature = HttpContext.Features.Get<IStatusCodePagesFeature>();
if (statusCodePagesFeature != null)
{
statusCodePagesFeature.Enabled = false;
}
}
Özel durum işleme kodu
Özel durum işleme sayfalarındaki kod da özel durumlar oluşturabilir. Üretim hata sayfaları kapsamlı bir şekilde test edilmeli ve kendi özel durumlarının oluşmasını önlemek için ek özen gösterilmelidir.
Yanıt üst bilgileri
Yanıtın üst bilgileri gönderildikten sonra:
- Uygulama yanıtın durum kodunu değiştiremez.
- Özel durum sayfaları veya işleyicileri çalıştırılamaz. Yanıt tamamlanmalıdır veya bağlantı durdurulmalıdır.
Sunucu özel durum işleme
Bir uygulamadaki özel durum işleme mantığına ek olarak, HTTP sunucusu uygulaması bazı özel durumları işleyebilir. Sunucu yanıt üst bilgileri gönderilmeden önce bir özel durum yakalarsa, yanıt gövdesi olmadan bir 500 - Internal Server Error
yanıt gönderir. Yanıt üst bilgileri gönderildikten sonra sunucu bir özel durum yakalarsa, sunucu bağlantıyı kapatır. Uygulama tarafından işlenmemiş istekler sunucu tarafından işlenir. Sunucu isteği işlerken oluşan özel durumlar, sunucunun özel durum işlemesi tarafından işlenir. Uygulamanın özel hata sayfaları, özel durum işleme ara yazılımı ve filtreler bu davranışı etkilemez.
Özel durum işlemeyi başlatma
Yalnızca barındırma katmanı, uygulama başlatma sırasında gerçekleşen özel durumları işleyebilir. Konak, başlangıç hatalarını yakalamak ve ayrıntılı hataları yakalamak için yapılandırılabilir.
Barındırma katmanı, yakalanan başlatma hatası için yalnızca ana bilgisayar adresi/bağlantı noktası bağlaması sonrasında hata oluşması durumunda bir hata sayfası gösterebilir. Bağlama başarısız olursa:
- Barındırma katmanı kritik bir özel durumu günlüğe kaydeder.
- dotnet işlemi kilitleniyor.
- HTTP sunucusu olduğunda hiçbir hata sayfası görüntülenmez Kestrel.
IIS (veya Azure Uygulaması Hizmeti) veya IIS Express üzerinde çalışırken, işlem başlatılamıyorsa ASP.NET Çekirdek Modülü tarafından 502.5 - İşlem Hatası döndürülür. Daha fazla bilgi için bkz. Azure Uygulaması Hizmeti ve IIS'de ASP.NET Core sorunlarını giderme.
Veritabanı hata sayfası
Veritabanı geliştirici sayfası özel durum filtresi AddDatabaseDeveloperPageExceptionFilter
, Entity Framework Core geçişleri kullanılarak çözümlenebilen veritabanıyla ilgili özel durumları yakalar. Bu özel durumlar oluştuğunda, sorunu çözmek için olası eylemlerin ayrıntılarıyla birlikte bir HTML yanıtı oluşturulur. Bu sayfa yalnızca Geliştirme ortamında etkinleştirilir. Tek tek kullanıcı hesapları belirtildiğinde, ASP.NET Temel Razor Sayfalar şablonları tarafından aşağıdaki kod oluşturuldu:
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(
Configuration.GetConnectionString("DefaultConnection")));
services.AddDatabaseDeveloperPageExceptionFilter();
services.AddDefaultIdentity<IdentityUser>(options => options.SignIn.RequireConfirmedAccount = true)
.AddEntityFrameworkStores<ApplicationDbContext>();
services.AddRazorPages();
}
Özel durum filtreleri
MVC uygulamalarında özel durum filtreleri genel olarak veya denetleyici başına veya eylem temelinde yapılandırılabilir. Razor Sayfalar uygulamalarında, bunlar genel olarak veya sayfa modeli başına yapılandırılabilir. Bu filtreler, bir denetleyici eyleminin veya başka bir filtrenin yürütülmesi sırasında oluşan işlenmeyen özel durumları işler. Daha fazla bilgi için bkz . ASP.NET Core'daki filtreler.
Özel durum filtreleri, MVC eylemleri içinde oluşan özel durumları yakalamak için kullanışlıdır, ancak yerleşik özel durum işleme ara yazılımıUseExceptionHandler
kadar esnek değildir. Hangi MVC eyleminin seçildiğine göre farklı hata işleme gerçekleştirmeniz gerekmediği sürece kullanmanızı UseExceptionHandler
öneririz.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapRazorPages();
});
}
Model durumu hataları
Model durumu hatalarını işleme hakkında bilgi için bkz . Model bağlama ve Model doğrulama.
Ek kaynaklar
Tarafından Tom Dykstra ve Steve Smith
Bu makalede, ASP.NET Core web uygulamalarında hataları işlemeye yönelik yaygın yaklaşımlar ele alınıyor. Bkz . Web API'leri için ASP.NET Core denetleyici tabanlı web API'lerindeki hataları işleme.
Örnek kodu görüntüleyin veya indirme. (nasıl indirilir.)
Geliştirici Özel Durum Sayfası
Geliştirici Özel Durum Sayfası, istek özel durumları hakkında ayrıntılı bilgiler görüntüler. ASP.NET Core şablonları aşağıdaki kodu oluşturur:
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
Yukarıdaki kod, uygulama Geliştirme ortamında çalışırken geliştirici özel durum sayfasını etkinleştirir.
Şablonlar herhangi bir ara yazılımdan önce yerleştirildiğinden UseDeveloperExceptionPage , aşağıdaki ara yazılımda özel durumlar yakalanmış olur.
Yukarıdaki kod, Geliştirici Özel Durum Sayfası'nı yalnızca uygulama Geliştirme ortamında çalışırken etkinleştirir. Uygulama üretimde çalıştırıldığında ayrıntılı özel durum bilgileri genel olarak görüntülenmemelidir. Ortamları yapılandırma hakkında daha fazla bilgi için bkz . ASP.NET Core'da birden çok ortam kullanma.
Geliştirici Özel Durum Sayfası, özel durum ve istek hakkında aşağıdaki bilgileri içerir:
- Yığın izleme
- Varsa sorgu dizesi parametreleri
- Varsa tanımlama bilgileri
- Üst Bilgiler
Özel durum işleyici sayfası
Üretim ortamı için özel hata işleme sayfası yapılandırmak için Özel Durum İşleme Ara Yazılımını kullanın. Ara yazılım:
- Özel durumları yakalar ve günlüğe kaydeder.
- Belirtilen sayfa veya denetleyici için isteği alternatif bir işlem hattında yeniden yürütür. Yanıt başlatıldıysa istek yeniden yürütülemez. Şablon tarafından oluşturulan kod isteği
/Error
için yeniden yürütür.
Aşağıdaki örnekte, UseExceptionHandler Geliştirme dışı ortamlarda Özel Durum İşleme Ara Yazılımını ekler:
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
Sayfalar uygulama şablonu, Razor Sayfalar klasöründe bir Hata sayfası (.cshtml
) ve PageModel sınıf (ErrorModel
) sağlar. Bir MVC uygulaması için proje şablonu, denetleyicide Home bir Hata eylem yöntemi ve Hata görünümü içerir.
Hata işleyicisi eylem yöntemini gibi HttpGet
HTTP yöntemi öznitelikleriyle işaretlemeyin. Açık fiiller, bazı isteklerin yöntemine ulaşmasını engeller. Kimliği doğrulanmamış kullanıcıların hata görünümünü görmesi gerekiyorsa yönteme anonim erişime izin verin.
Özel duruma erişme
Hata işleyici denetleyicisinde veya sayfasında özel duruma ve özgün istek yoluna erişmek için kullanın IExceptionHandlerPathFeature :
[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
public class ErrorModel : PageModel
{
public string RequestId { get; set; }
public bool ShowRequestId => !string.IsNullOrEmpty(RequestId);
public string ExceptionMessage { get; set; }
public void OnGet()
{
RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier;
var exceptionHandlerPathFeature =
HttpContext.Features.Get<IExceptionHandlerPathFeature>();
if (exceptionHandlerPathFeature?.Error is FileNotFoundException)
{
ExceptionMessage = "File error thrown";
}
if (exceptionHandlerPathFeature?.Path == "/index")
{
ExceptionMessage += " from home page";
}
}
}
Uyarı
Hassas hata bilgilerini istemcilere sunma. Hata sunma bir güvenlik riskidir.
Önceki özel durum işleme sayfasını tetikleme için ortamı üretimler olarak ayarlayın ve bir özel durum zorlaması gerçekleştirin.
Özel durum işleyici lambda
Özel özel durum işleyici sayfasının alternatifi, öğesine UseExceptionHandlerbir lambda sağlamaktır. Lambda kullanmak, yanıtı döndürmeden önce hataya erişim sağlar.
Özel durum işleme için lambda kullanma örneği aşağıda verilmişti:
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler(errorApp =>
{
errorApp.Run(async context =>
{
context.Response.StatusCode = (int) HttpStatusCode.InternalServerError;
context.Response.ContentType = "text/html";
await context.Response.WriteAsync("<html lang=\"en\"><body>\r\n");
await context.Response.WriteAsync("ERROR!<br><br>\r\n");
var exceptionHandlerPathFeature =
context.Features.Get<IExceptionHandlerPathFeature>();
if (exceptionHandlerPathFeature?.Error is FileNotFoundException)
{
await context.Response.WriteAsync("File error thrown!<br><br>\r\n");
}
await context.Response.WriteAsync("<a href=\"/\">Home</a><br>\r\n");
await context.Response.WriteAsync("</body></html>\r\n");
await context.Response.WriteAsync(new string(' ', 512)); // IE padding
});
});
app.UseHsts();
}
Yukarıdaki koda, await context.Response.WriteAsync(new string(' ', 512));
Internet Explorer tarayıcısının IE hata iletisi yerine hata iletisini görüntülemesi için eklenir. Daha fazla bilgi için bu GitHub konusuna bakın.
Uyarı
İstemcilerden veya istemcilere hassas hata bilgileri sağlamayınIExceptionHandlerFeature.IExceptionHandlerPathFeature Hata sunma bir güvenlik riskidir.
Örnek uygulamada özel durum işleme lambdasının sonucunu görmek için ve ErrorHandlerLambda
önişlemci yönergelerini kullanın ProdEnvironment
ve sayfada Bir özel durum tetikle'yi home seçin.
UseStatusCodePages
Varsayılan olarak, ASP.NET Core uygulaması HTTP durum kodları için 404 - Bulunamadı gibi bir durum kodu sayfası sağlamaz. Uygulama bir durum kodu ve boş bir yanıt gövdesi döndürür. Durum kodu sayfaları sağlamak için Durum Kodu Sayfaları ara yazılımını kullanın.
Ara yazılım, Microsoft.AspNetCore.Diagnostics paketi tarafından kullanılabilir hale getirilir.
Yaygın hata durum kodları için varsayılan yalnızca metin işleyicilerini etkinleştirmek için yöntemini çağırın UseStatusCodePages Startup.Configure
:
app.UseStatusCodePages();
İstek işleme ara yazılımından önce çağrı UseStatusCodePages
(örneğin, Statik Dosya Ara Yazılımı ve MVC Ara Yazılımı).
Kullanılmadığında UseStatusCodePages
, uç nokta olmadan BIR URL'ye gitmek, uç noktanın bulunamadığını belirten tarayıcıya bağımlı bir hata iletisi döndürür. Örneğin, adresine gitmek.Home/Privacy2
Çağrıldığında UseStatusCodePages
tarayıcı şunu döndürür:
Status Code: 404; Not Found
Biçim dizesi ile UseStatusCodePages
Yanıt içerik türünü ve metnini özelleştirmek için, bir içerik türü ve biçim dizesi alan öğesinin aşırı yüklemesini UseStatusCodePages kullanın:
app.UseStatusCodePages(
"text/plain", "Status code page, status code: {0}");
Lambda ile UseStatusCodePages
Özel hata işleme ve yanıt yazma kodu belirtmek için bir lambda ifadesi alan öğesinin aşırı yüklemesini UseStatusCodePages kullanın:
app.UseStatusCodePages(async context =>
{
context.HttpContext.Response.ContentType = "text/plain";
await context.HttpContext.Response.WriteAsync(
"Status code page, status code: " +
context.HttpContext.Response.StatusCode);
});
UseStatusCodePagesWithRedirects
UseStatusCodePagesWithRedirects Uzantı yöntemi:
- İstemciye bir 302 - Bulundu durum kodu gönderir.
- İstemciyi URL şablonunda sağlanan konuma yönlendirir.
app.UseStatusCodePagesWithRedirects("/StatusCode?code={0}");
URL şablonu, örnekte gösterildiği gibi durum kodu için bir {0}
yer tutucu içerebilir. URL şablonu (tilde) ile ~
başlıyorsa, ~
yerine uygulamanın PathBase
olur. Uygulama içindeki bir uç noktaya işaret ederseniz, uç nokta için bir MVC görünümü veya Razor sayfası oluşturun. Razor Sayfalar örneği için örnek uygulamada bölümüne bakın Pages/StatusCode.cshtml
.
Bu yöntem genellikle uygulama şu durumlarda kullanılır:
- genellikle farklı bir uygulamanın hatayı işlediği durumlarda istemciyi farklı bir uç noktaya yönlendirmelidir. Web uygulamaları için istemcinin tarayıcı adres çubuğu yeniden yönlendirilen uç noktayı yansıtır.
- İlk yeniden yönlendirme yanıtıyla özgün durum kodunu korumamalı ve döndürmemelidir.
UseStatusCodePagesWithReExecute
UseStatusCodePagesWithReExecute Uzantı yöntemi:
- İstemciye özgün durum kodunu döndürür.
- Alternatif bir yol kullanarak istek işlem hattını yeniden yürüterek yanıt gövdesini oluşturur.
app.UseStatusCodePagesWithReExecute("/StatusCode","?code={0}");
Uygulama içindeki bir uç noktaya işaret ederseniz, uç nokta için bir MVC görünümü veya Razor sayfası oluşturun. İsteğin durum sayfasına yeniden yönlendirilmesi için önce UseRouting
yerleştirildiğinden emin olunUseStatusCodePagesWithReExecute
. Razor Sayfalar örneği için örnek uygulamada bölümüne bakın Pages/StatusCode.cshtml
.
Bu yöntem genellikle uygulamanın aşağıdakileri yapması gerektiğinde kullanılır:
- İsteği farklı bir uç noktaya yeniden yönlendirmeden işleyin. Web uygulamaları için istemcinin tarayıcı adres çubuğu başlangıçta istenen uç noktayı yansıtır.
- Yanıtla birlikte özgün durum kodunu koruyun ve döndürin.
URL ve sorgu dizesi şablonları durum kodu için bir yer tutucu ({0}
) içerebilir. URL şablonunun eğik çizgiyle (/
) başlaması gerekir. Yolda yer tutucu kullanırken uç noktanın (sayfa veya denetleyici) yol kesimini işleyebildiğini onaylayın. Örneğin, hatalar için Bir Razor Sayfa isteğe bağlı yol kesim değerini şu yönergeyle @page
kabul etmelidir:
@page "{code?}"
Hatayı işleyen uç nokta, aşağıdaki örnekte gösterildiği gibi hatayı oluşturan özgün URL'yi alabilir:
var statusCodeReExecuteFeature = HttpContext.Features.Get<IStatusCodeReExecuteFeature>();
if (statusCodeReExecuteFeature != null)
{
OriginalURL =
statusCodeReExecuteFeature.OriginalPathBase
+ statusCodeReExecuteFeature.OriginalPath
+ statusCodeReExecuteFeature.OriginalQueryString;
}
Hata işleyicisi eylem yöntemini gibi HttpGet
HTTP yöntemi öznitelikleriyle işaretlemeyin. Açık fiiller, bazı isteklerin yöntemine ulaşmasını engeller. Kimliği doğrulanmamış kullanıcıların hata görünümünü görmesi gerekiyorsa yönteme anonim erişime izin verin.
Durum kodu sayfalarını devre dışı bırakma
MVC denetleyicisinin veya eylem yönteminin durum kodu sayfalarını devre dışı bırakmak için özniteliğini [SkipStatusCodePages]
kullanın.
Pages işleyici yönteminde veya MVC denetleyicisinde Razor belirli istekler için durum kodu sayfalarını devre dışı bırakmak için kullanın IStatusCodePagesFeature:
var statusCodePagesFeature = HttpContext.Features.Get<IStatusCodePagesFeature>();
if (statusCodePagesFeature != null)
{
statusCodePagesFeature.Enabled = false;
}
Özel durum işleme kodu
Özel durum işleme sayfalarındaki kod özel durumlar oluşturabilir. Genellikle üretim hata sayfalarının tamamen statik içeriklerden oluşması iyi bir fikirdir.
Yanıt üst bilgileri
Yanıtın üst bilgileri gönderildikten sonra:
- Uygulama yanıtın durum kodunu değiştiremez.
- Özel durum sayfaları veya işleyicileri çalıştırılamaz. Yanıt tamamlanmalıdır veya bağlantı durdurulmalıdır.
Sunucu özel durum işleme
Uygulamanızdaki özel durum işleme mantığına ek olarak, HTTP sunucusu uygulaması bazı özel durumları işleyebilir. Yanıt üst bilgileri gönderilmeden önce sunucu bir özel durum yakalarsa, sunucu yanıt gövdesi olmadan 500 - İç Sunucu Hatası yanıtı gönderir. Yanıt üst bilgileri gönderildikten sonra sunucu bir özel durum yakalarsa, sunucu bağlantıyı kapatır. Uygulamanız tarafından işlenmemiş istekler sunucu tarafından işlenir. Sunucu isteği işlerken oluşan özel durumlar, sunucunun özel durum işlemesi tarafından işlenir. Uygulamanın özel hata sayfaları, özel durum işleme ara yazılımı ve filtreler bu davranışı etkilemez.
Özel durum işlemeyi başlatma
Yalnızca barındırma katmanı, uygulama başlatma sırasında gerçekleşen özel durumları işleyebilir. Konak, başlangıç hatalarını yakalamak ve ayrıntılı hataları yakalamak için yapılandırılabilir.
Barındırma katmanı, yakalanan başlatma hatası için yalnızca ana bilgisayar adresi/bağlantı noktası bağlaması sonrasında hata oluşması durumunda bir hata sayfası gösterebilir. Bağlama başarısız olursa:
- Barındırma katmanı kritik bir özel durumu günlüğe kaydeder.
- dotnet işlemi kilitleniyor.
- HTTP sunucusu olduğunda hiçbir hata sayfası görüntülenmez Kestrel.
IIS (veya Azure Uygulaması Hizmeti) veya IIS Express üzerinde çalışırken, işlem başlatılamıyorsa ASP.NET Çekirdek Modülü tarafından 502.5 - İşlem Hatası döndürülür. Daha fazla bilgi için bkz. Azure Uygulaması Hizmeti ve IIS'de ASP.NET Core sorunlarını giderme.
Veritabanı hata sayfası
Veritabanı Hata Sayfası Ara Yazılımı, Entity Framework geçişleri kullanılarak çözümlenebilen veritabanıyla ilgili özel durumları yakalar. Bu özel durumlar oluştuğunda, sorunu çözmek için olası eylemlerin ayrıntılarını içeren bir HTML yanıtı oluşturulur. Bu sayfa yalnızca Geliştirme ortamında etkinleştirilmelidir. sayfasına kod ekleyerek sayfayı Startup.Configure
etkinleştirin:
if (env.IsDevelopment())
{
app.UseDatabaseErrorPage();
}
UseDatabaseErrorPageMicrosoft.AspNetCore.Diagnostics.EntityFrameworkCore NuGet paketini gerektirir.
Özel durum filtreleri
MVC uygulamalarında özel durum filtreleri genel olarak veya denetleyici başına veya eylem temelinde yapılandırılabilir. Razor Sayfalar uygulamalarında, bunlar genel olarak veya sayfa modeli başına yapılandırılabilir. Bu filtreler, bir denetleyici eyleminin veya başka bir filtrenin yürütülmesi sırasında oluşan işlenmeyen özel durumları işler. Daha fazla bilgi için bkz . ASP.NET Core'daki filtreler.
İpucu
Özel durum filtreleri, MVC eylemleri içinde oluşan özel durumları yakalamak için kullanışlıdır, ancak Özel Durum İşleme Ara Yazılımı kadar esnek değildir. Ara yazılımı kullanmanızı öneririz. Filtreleri yalnızca hangi MVC eyleminin seçildiğine göre farklı hata işleme gerçekleştirmeniz gerektiğinde kullanın.
Model durumu hataları
Model durumu hatalarını işleme hakkında bilgi için bkz . Model bağlama ve Model doğrulama.
Ek kaynaklar
ASP.NET Core