Not
Bu sayfaya erişim yetkilendirme gerektiriyor. Oturum açmayı veya dizinleri değiştirmeyi deneyebilirsiniz.
Bu sayfaya erişim yetkilendirme gerektiriyor. Dizinleri değiştirmeyi deneyebilirsiniz.
Note
Bu, bu makalenin en son sürümü değildir. Geçerli sürüm için bu makalenin .NET 10 sürümüne bakın.
Warning
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 9 sürümüne bakın.
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 Çekirdek API'lerindeki 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. Bu, HTTP işlem hattından zaman uyumlu ve zaman uyumsuz özel durumları yakalamak ve hata yanıtları oluşturmak için DeveloperExceptionPageMiddleware kullanır. Geliştirici özel durum sayfası, ara yazılım işlem hattının başlarında devreye girer, 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.
Daha önceki şablonlar, yani WebHost.CreateDefaultBuilder kullanılarak oluşturulan uygulamalar, app.UseDeveloperExceptionPage çağrılarak geliştirici özel durum sayfasını etkinleştirebilir.
Warning
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 çalışma zamanı ortamları.
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 çerezler
- Headers
- 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ük ö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 tekrar çalıştırılamaz. Şablon tarafından oluşturulan kod,
/Erroryolunu kullanarak isteği yeniden yürütür.
Warning
Alternatif işlem hattı kendine özgü bir özel durum oluşturursa, Özel Durum İşleme Ara Yazılımı özgün özel durumu yeniden fırlatır.
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 genellikle,
_nextçağrısından sonra durumlarını temizlemek veya işlemi yeniden yapmaktan kaçınmak için işlemleriniHttpContextüzerinde önbelleğe almak anlamına gelir. İstek gövdesiyle ilgilenirken bu, sonuçları Form okuyucusu gibi arabelleğe veya önbelleğe almak 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 Error bir Home 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
OnGetve 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, fırlatılan özel durum hakkında daha fazla bilgi almak için IExceptionHandlerPathFeature kullanır.
[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.";
}
}
}
Warning
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
});
}
Warning
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. Arayüz, TryHandleAsync ve HttpContext parametrelerini alan tek bir Exception yöntem içerir.
IExceptionHandler gerçekleştirmeler, IServiceCollection.AddExceptionHandler<T> çağrılarak kaydedilir. Bir IExceptionHandler örneğin ömrü tektir. Birden çok uygulama eklenebilir ve bunlar kayıtlı sırayla çağrılır.
Özel durum işleme ara yazılımı, kayıtlı özel durum işleyicileri sırayla döngüyle dolaşarak, bir tanesi true'den gelen TryHandleAsync döndürene kadar devam eder, bu da özel durumun işlendiğini gösterir. Özel durum işleyicisi bir özel durumu işlerse, işlemeyi durdurmak için true değerini döndürebilir. Bir özel durum herhangi bir işleyici tarafından ele alınmazsa, kontrol ara yazılımın varsayılan davranış ve seçeneklerine geri döner.
.NET 10'dan başlayarak varsayılan davranış, işlenen özel durumlar için günlükler ve ölçümler gibi tanılamaların emisyonunu engellemektir (döndürdüğünde TryHandleAsynctrue). Bu, özel durumun işlenip işlenmediğine bakılmaksızın tanılamaların her zaman yayıldığı önceki sürümlerden (.NET 8 ve 9) farklıdır.
SuppressDiagnosticsCallback ayarlanarak varsayılan davranış değiştirilebilir.
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:
-
CustomExceptionHandlerbir özel durumu işlemek için ilk olarak çağrılır. - Özel durum kaydedildikten sonra,
TryHandleAsyncyöntemifalsedöndürür, bu nedenle geliştirici özel durum sayfası gösterilir.
Diğer ortamlarda:
-
CustomExceptionHandlerbir özel durumu işlemek için ilk olarak çağrılır. - Özel durumu
TryHandleAsyncgünlüğe kaydettikten sonra yöntemi döndürürfalse, böylece/Errorsayfa gösterilir.
SuppressDiagnosticsCallback
.NET 10'dan başlayarak, özel durum işleme ara yazılımındaki SuppressDiagnosticsCallback üzerindeki ExceptionHandlerOptions özelliğini yapılandırarak işlenen özel durumlar için tanılama yazılıp yazılmadığını denetleyebilirsiniz. Bu geri çağırma özel durum bağlamını alır ve teşhis işlemlerinin belirli bir özel durum veya isteğe göre bastırılıp bastırılmayacağını belirlemenize olanak tanır.
.NET 8 ve 9 davranışına geri dönmek için geri çağırmayı, işlenen özel durumlar için tanılamaların her zaman yayıldığı şekilde ayarlayın; bu durumda geri çağırma her zaman false döner.
app.UseExceptionHandler(new ExceptionHandlerOptions
{
SuppressDiagnosticsCallback = context => false
});
Ayrıca, özel durum türüne veya başka bir bağlama göre tanılamaları koşullu olarak gizleyebilirsiniz:
app.UseExceptionHandler(new ExceptionHandlerOptions
{
SuppressDiagnosticsCallback = context => context.Exception is ArgumentException
});
IExceptionHandler'nin herhangi bir uygulaması tarafından bir özel durum işlenmediğinde (tüm işleyiciler false döner TryHandleAsync), kontrol ara yazılımdan gelen varsayılan davranışa ve seçeneklere geri döner ve tanılamalar ara yazılımın standart davranışına göre oluşturulur.
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();
Çağırın UseStatusCodePages istek işleme ara yazılımını çalıştırmadan önce. Ö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.
Note
Durum kodu sayfaları ara yazılımı istisnaları 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 kodunu belirtmek için bir lambda ifadesi alan UseStatusCodePages'ın aşırı yükleme işlevini 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, ~ uygulamanın PathBase'si ile değiştirilir. 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 UseStatusCodePagesWithReExecutegeç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 genellikle,
_nextçağrısından sonra durumlarını temizlemek veya işlemi yeniden yapmaktan kaçınmak için işlemleriniHttpContextüzerinde önbelleğe almak anlamına gelir. İstek gövdesiyle ilgilenirken bu, sonuçları Form okuyucusu gibi arabelleğe veya önbelleğe almak 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 fırlatabilir. Ü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 başlıkları
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 durumu 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 çöküyor.
- 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çermemesiAddProblemDetailsAccept
- 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
Acceptiçermediğinde 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.CustomizeProblemDetailskomutunu kullanma - Özelleştirilmiş bir
IProblemDetailsWriterkullanın - Orta katmanda
IProblemDetailsServiceçağırın
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.
Aşağıdaki kod, ProblemDetailsOptions kullanarak CustomizeProblemDetails'yi ayarlar:
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"
}
** Özel 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, IProblemDetailsWriter, AddRazorPages, AddControllers veya AddControllersWithViews çağrılmadan önce özel AddMvc öğesinin 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ı
ProblemDetailsOptions ile CustomizeProblemDetails kullanmaya alternatif bir yaklaşım, ProblemDetails'yi ara yazılımda ayarlamaktır. Bir sorun ayrıntıları yanıtı, IProblemDetailsService.WriteAsync çağrılarak 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ı IProblemDetailsService.WriteAsync çağrılmadan önce yazılır ve yanıt yeniden yazılmaz.
Aşağıdaki ValuesController yanıt akışına yazdığı için özel sorun yanıtının döndürülmesini önleyen BadRequestResult döndürür.
[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 ControllerBase.Problem döndürülür:
[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));
}
}
İstisnalar için ProblemDetails yükü oluşturun
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, hatalara erişim sağlar ve IProblemDetailsService.WriteAsync ile sorun ayrıntıları ile bir 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();
Warning
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
- Örnek kodu görüntüleme veya indirme (indirme)
- Azure App Service ve IIS'de ASP.NET Core sorunlarını giderme
- ASP.NET Core ile Azure App Service ve IIS için yaygın hataları giderme
- ASP.NET Core API'lerindeki hataları işleme
-
Hataya neden olan değişiklik: True döndürdüğünde
IExceptionHandler.TryHandleAsyncözel durum tanılamaları gizleniyor
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 Çekirdek API'lerindeki 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. Bu, HTTP işlem hattından zaman uyumlu ve zaman uyumsuz özel durumları yakalamak ve hata yanıtları oluşturmak için DeveloperExceptionPageMiddleware kullanır. Geliştirici özel durum sayfası, ara yazılım işlem hattının başlarında devreye girer, 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.
Daha önceki şablonlar, yani WebHost.CreateDefaultBuilder kullanılarak oluşturulan uygulamalar, app.UseDeveloperExceptionPage çağrılarak geliştirici özel durum sayfasını etkinleştirebilir.
Warning
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 çalışma zamanı ortamları.
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 çerezler
- Headers
- 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ük ö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 tekrar çalıştırılamaz. Şablon tarafından oluşturulan kod,
/Erroryolunu kullanarak isteği yeniden yürütür.
Warning
Alternatif işlem hattı kendine özgü bir özel durum oluşturursa, Özel Durum İşleme Ara Yazılımı özgün özel durumu yeniden fırlatır.
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 genellikle,
_nextçağrısından sonra durumlarını temizlemek veya işlemi yeniden yapmaktan kaçınmak için işlemleriniHttpContextüzerinde önbelleğe almak anlamına gelir. İstek gövdesiyle ilgilenirken bu, sonuçları Form okuyucusu gibi arabelleğe veya önbelleğe almak 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 Error bir Home 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
OnGetve 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, fırlatılan özel durum hakkında daha fazla bilgi almak için IExceptionHandlerPathFeature kullanır.
[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.";
}
}
}
Warning
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
});
}
Warning
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 gerçekleştirmeler, IServiceCollection.AddExceptionHandler<T> çağrılarak kaydedilir. Bir IExceptionHandler örneğin ömrü tektir. 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 herhangi bir işleyici tarafından ele alınmazsa, kontrol ara yazılımın varsayılan davranış ve seçeneklerine geri döner. İşlenen ve işlenmeyen özel durumlar için farklı ölçümler ve günlükler üretilir.
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:
-
CustomExceptionHandlerbir özel durumu işlemek için ilk olarak çağrılır. - Özel durum kaydedildikten sonra,
TryHandleAsyncyöntemifalsedöndürür, bu nedenle geliştirici özel durum sayfası gösterilir.
Diğer ortamlarda:
-
CustomExceptionHandlerbir özel durumu işlemek için ilk olarak çağrılır. - Özel durumu
TryHandleAsyncgünlüğe kaydettikten sonra yöntemi döndürürfalse, böylece/Errorsayfa 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();
Çağırın UseStatusCodePages istek işleme ara yazılımını çalıştırmadan önce. Ö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.
Note
Durum kodu sayfaları ara yazılımı istisnaları 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 kodunu belirtmek için bir lambda ifadesi alan UseStatusCodePages'ın aşırı yükleme işlevini 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, ~ uygulamanın PathBase'si ile değiştirilir. 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 UseStatusCodePagesWithReExecutegeç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 genellikle,
_nextçağrısından sonra durumlarını temizlemek veya işlemi yeniden yapmaktan kaçınmak için işlemleriniHttpContextüzerinde önbelleğe almak anlamına gelir. İstek gövdesiyle ilgilenirken bu, sonuçları Form okuyucusu gibi arabelleğe veya önbelleğe almak 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 fırlatabilir. Ü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 başlıkları
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 durumu 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 çöküyor.
- 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çermemesiAddProblemDetailsAccept
- 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
Acceptiçermediğinde 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.CustomizeProblemDetailskomutunu kullanma - Özelleştirilmiş bir
IProblemDetailsWriterkullanın - Orta katmanda
IProblemDetailsServiceçağırın
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.
Aşağıdaki kod, ProblemDetailsOptions kullanarak CustomizeProblemDetails'yi ayarlar:
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"
}
** Özel 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, IProblemDetailsWriter, AddRazorPages, AddControllers veya AddControllersWithViews çağrılmadan önce özel AddMvc öğesinin 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ı
ProblemDetailsOptions ile CustomizeProblemDetails kullanmaya alternatif bir yaklaşım, ProblemDetails'yi ara yazılımda ayarlamaktır. Bir sorun ayrıntıları yanıtı, IProblemDetailsService.WriteAsync çağrılarak 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ı IProblemDetailsService.WriteAsync çağrılmadan önce yazılır ve yanıt yeniden yazılmaz.
Aşağıdaki ValuesController yanıt akışına yazdığı için özel sorun yanıtının döndürülmesini önleyen BadRequestResult döndürür.
[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 ControllerBase.Problem döndürülür:
[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));
}
}
İstisnalar için ProblemDetails yükü oluşturun
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, hatalara erişim sağlar ve IProblemDetailsService.WriteAsync ile sorun ayrıntıları ile bir 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();
Warning
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 Çekirdek 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.CreateDefaultBuilderiçindeapp.UseDeveloperExceptionPagearayarakConfiguregeliştirici özel durum sayfasını etkinleştirmelidir.
Geliştirici özel durum sayfası, ara yazılım işlem hattının başlarında devreye girer, 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 çalışma zamanı ortamları.
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 çerezler
- Headers
Geliştirici Özel Durum Sayfası'nın herhangi bir bilgi sağlaması garanti değildir. Tam hata bilgileri için Günlük ö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 tekrar çalıştırılamaz. Şablon tarafından oluşturulan kod,
/Erroryolunu kullanarak isteği yeniden yürütür.
Warning
Alternatif işlem hattı kendine özgü bir özel durum oluşturursa, Özel Durum İşleme Ara Yazılımı özgün özel durumu yeniden fırlatır.
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 genellikle,
_nextçağrısından sonra durumlarını temizlemek veya işlemi yeniden yapmaktan kaçınmak için işlemleriniHttpContextüzerinde önbelleğe almak anlamına gelir. İstek gövdesiyle ilgilenirken bu, sonuçları Form okuyucusu gibi arabelleğe veya önbelleğe almak 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 Error bir Home 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
OnGetve 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, fırlatılan özel durum hakkında daha fazla bilgi almak için IExceptionHandlerPathFeature kullanır.
[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.";
}
}
}
Warning
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();
}
Warning
Hassas hata bilgilerini istemcilere sunma. Hata sunma bir güvenlik riskidir.
IExceptionHandler
IExceptionHandler, geliştiriciye merkezi bir konumdaki bilinen özel durumları işlemek için geri çağırma sağlayan bir arabirimdir.
IExceptionHandler uygulamaları, IServiceCollection.AddExceptionHandler<T> [IServiceCollection.AddExceptionHandler<T>] çağrılarak kaydedilir. Bir IExceptionHandler örneğin ömrü tektir. 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 herhangi bir işleyici tarafından ele alınmazsa, kontrol ara yazılımın varsayılan davranış ve seçeneklerine geri döner. İşlenen ve işlenmeyen özel durumlar için farklı ölçümler ve günlükler üretilir.
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:
-
CustomExceptionHandlerbir özel durumu işlemek için ilk olarak çağrılır. - Özel durum kaydedildikten sonra,
TryHandleExceptionyöntemifalsedöndürür, bu nedenle geliştirici özel durum sayfası gösterilir.
Diğer ortamlarda:
-
CustomExceptionHandlerbir özel durumu işlemek için ilk olarak çağrılır. - Özel durumu
TryHandleExceptiongünlüğe kaydettikten sonra yöntemi döndürürfalse, böylece/Errorsayfa 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();
Çağırın UseStatusCodePages istek işleme ara yazılımını çalıştırmadan önce. Ö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.
Note
Durum kodu sayfaları ara yazılımı istisnaları 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 kodunu belirtmek için bir lambda ifadesi alan UseStatusCodePages'ın aşırı yükleme işlevini 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, ~ uygulamanın PathBase'si ile değiştirilir. 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 UseStatusCodePagesWithReExecutegeç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 genellikle,
_nextçağrısından sonra durumlarını temizlemek veya işlemi yeniden yapmaktan kaçınmak için işlemleriniHttpContextüzerinde önbelleğe almak anlamına gelir. İstek gövdesiyle ilgilenirken bu, sonuçları Form okuyucusu gibi arabelleğe veya önbelleğe almak 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 fırlatabilir. Ü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 başlıkları
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 durumu 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 çöküyor.
- 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çermemesiAddProblemDetailsAccept
- 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
Acceptiçermediğinde 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.CustomizeProblemDetailskomutunu kullanma - Özelleştirilmiş bir
IProblemDetailsWriterkullanın - Orta katmanda
IProblemDetailsServiceçağırın
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.
Aşağıdaki kod, ProblemDetailsOptions kullanarak CustomizeProblemDetails'yi ayarlar:
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"
}
** Özel 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, IProblemDetailsWriter, AddRazorPages, AddControllers veya AddControllersWithViews çağrılmadan önce özel AddMvc öğesinin 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ı
ProblemDetailsOptions ile CustomizeProblemDetails kullanmaya alternatif bir yaklaşım, ProblemDetails'yi ara yazılımda ayarlamaktır. Bir sorun ayrıntıları yanıtı, IProblemDetailsService.WriteAsync çağrılarak 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ı IProblemDetailsService.WriteAsync çağrılmadan önce yazılır ve yanıt yeniden yazılmaz.
Aşağıdaki ValuesController yanıt akışına yazdığı için özel sorun yanıtının döndürülmesini önleyen BadRequestResult döndürür.
[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 ControllerBase.Problem döndürülür:
[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));
}
}
İstisnalar için ProblemDetails yükü oluşturun
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, hatalara erişim sağlar ve IProblemDetailsService.WriteAsync ile sorun ayrıntıları ile bir 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();
Warning
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 Çekirdek 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.CreateDefaultBuilderiçindeapp.UseDeveloperExceptionPagearayarakConfiguregeliştirici özel durum sayfasını etkinleştirmelidir.
Geliştirici özel durum sayfası, ara yazılım işlem hattının başlarında devreye girer, 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 çalışma zamanı ortamları.
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 çerezler
- Headers
Geliştirici Özel Durum Sayfası'nın herhangi bir bilgi sağlaması garanti değildir. Tam hata bilgileri için Günlük ö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 tekrar çalıştırılamaz. Şablon tarafından oluşturulan kod,
/Erroryolunu kullanarak isteği yeniden yürütür.
Warning
Alternatif işlem hattı kendine özgü bir özel durum oluşturursa, Özel Durum İşleme Ara Yazılımı özgün özel durumu yeniden fırlatır.
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 genellikle,
_nextçağrısından sonra durumlarını temizlemek veya işlemi yeniden yapmaktan kaçınmak için işlemleriniHttpContextüzerinde önbelleğe almak anlamına gelir. İstek gövdesiyle ilgilenirken bu, sonuçları Form okuyucusu gibi arabelleğe veya önbelleğe almak 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 Error bir Home 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
OnGetve 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, fırlatılan özel durum hakkında daha fazla bilgi almak için IExceptionHandlerPathFeature kullanır.
[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.";
}
}
}
Warning
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();
}
Warning
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();
Çağırın UseStatusCodePages istek işleme ara yazılımını çalıştırmadan önce. Ö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.
Note
Durum kodu sayfaları ara yazılımı istisnaları 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 kodunu belirtmek için bir lambda ifadesi alan UseStatusCodePages'ın aşırı yükleme işlevini 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, ~ uygulamanın PathBase'si ile değiştirilir. 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 UseStatusCodePagesWithReExecutegeç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 genellikle,
_nextçağrısından sonra durumlarını temizlemek veya işlemi yeniden yapmaktan kaçınmak için işlemleriniHttpContextüzerinde önbelleğe almak anlamına gelir. İstek gövdesiyle ilgilenirken bu, sonuçları Form okuyucusu gibi arabelleğe veya önbelleğe almak 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 fırlatabilir. Ü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 başlıkları
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 durumu 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 çöküyor.
- 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çermemesiAddProblemDetailsAccept
- 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
Acceptiçermediğinde 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.CustomizeProblemDetailskomutunu kullanma - Özelleştirilmiş bir
IProblemDetailsWriterkullanın - Orta katmanda
IProblemDetailsServiceçağırın
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.
Aşağıdaki kod, ProblemDetailsOptions kullanarak CustomizeProblemDetails'yi ayarlar:
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"
}
** Özel 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, IProblemDetailsWriter, AddRazorPages, AddControllers veya AddControllersWithViews çağrılmadan önce özel AddMvc öğesinin 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ı
ProblemDetailsOptions ile CustomizeProblemDetails kullanmaya alternatif bir yaklaşım, ProblemDetails'yi ara yazılımda ayarlamaktır. Bir sorun ayrıntıları yanıtı, IProblemDetailsService.WriteAsync çağrılarak 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ı IProblemDetailsService.WriteAsync çağrılmadan önce yazılır ve yanıt yeniden yazılmaz.
Aşağıdaki ValuesController yanıt akışına yazdığı için özel sorun yanıtının döndürülmesini önleyen BadRequestResult döndürür.
[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 ControllerBase.Problem döndürülür:
[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));
}
}
İstisnalar için ProblemDetails yükü oluşturun
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, hatalara erişim sağlar ve IProblemDetailsService.WriteAsync ile sorun ayrıntıları ile bir 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();
Warning
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 Çekirdek 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.CreateDefaultBuilderiçindeapp.UseDeveloperExceptionPagearayarakConfiguregeliştirici özel durum sayfasını etkinleştirmelidir.
Geliştirici özel durum sayfası, ara yazılım işlem hattının başlarında devreye girer, 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 çalışma zamanı ortamları.
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 çerezler
- Headers
Geliştirici Özel Durum Sayfası'nın herhangi bir bilgi sağlaması garanti değildir. Tam hata bilgileri için Günlük ö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 tekrar çalıştırılamaz. Şablon tarafından oluşturulan kod,
/Erroryolunu kullanarak isteği yeniden yürütür.
Warning
Alternatif işlem hattı kendine özgü bir özel durum oluşturursa, Özel Durum İşleme Ara Yazılımı özgün özel durumu yeniden fırlatı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 Error bir Home 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
OnGetve 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, fırlatılan özel durum hakkında daha fazla bilgi almak için IExceptionHandlerPathFeature kullanır.
[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.";
}
}
}
Warning
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();
}
Warning
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();
Çağırın UseStatusCodePages istek işleme ara yazılımını çalıştırmadan önce. Ö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.
Note
Durum kodu sayfaları ara yazılımı istisnaları 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 kodunu belirtmek için bir lambda ifadesi alan UseStatusCodePages'ın aşırı yükleme işlevini 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, ~ uygulamanın PathBase'si ile değiştirilir. 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 UseStatusCodePagesWithReExecutegeç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 fırlatabilir. Ü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 başlıkları
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 durumu 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 çöküyor.
- 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 Çekirdek 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 UseDeveloperExceptionPage'yu ara yazılım işlem hattının erken aşamalarına yerleştirir, böylece sonraki ara yazılımda meydana gelen işlenmeyen özel durumları yakalayabilir.
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 çalışma zamanı ortamları.
Geliştirici Özel Durum Sayfası, özel durum ve istek hakkında aşağıdaki bilgileri içerebilir:
- Yığın izleme
- Varsa sorgu dizesi parametreleri
- Tanımlama bilgileri, varsa
- Headers
Geliştirici Özel Durum Sayfası'nın herhangi bir bilgi sağlaması garanti değildir. Tam hata bilgileri için Günlük ö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 tekrar çalıştırılamaz. Şablon tarafından oluşturulan kod,
/Erroryolunu kullanarak isteği yeniden yürütür.
Warning
Alternatif işlem hattı kendine özgü bir özel durum oluşturursa, Özel Durum İşleme Ara Yazılımı özgün özel durumu yeniden fırlatır.
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 Error bir Home 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
OnGetve 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 ExceptionMessage'e Pages/Error.cshtml.cs ekler.
[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";
}
}
}
Warning
Hassas hata bilgilerini istemcilere sunma. Hata sunma bir güvenlik riskidir.
Örnek uygulamada özel durumu test etmek için:
- Ortamı üretim olarak ayarlayın.
-
webBuilder.UseStartup<Startup>();içindeki yorumlarıProgram.cskaldırın. - Ana sayfada Bir özel durumu tetikleyin 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();
});
}
Warning
İstemcilereIExceptionHandlerFeature veya IExceptionHandlerPathFeature üzerinden hassas hata bilgileri sağlamayın. Hata sunma bir güvenlik riskidir.
Örnek uygulamada özel durum işleme lamdasını test etmek için:
- Ortamı üretim olarak ayarlayın.
-
webBuilder.UseStartup<StartupLambda>();içindeki yorumlarıProgram.cskaldırın. - Ana sayfada Bir özel durumu tetikleyin 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 amacıyla, UseStatusCodePages yöntemi içinde Startup.Configure çağırın.
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();
});
}
Çağırın UseStatusCodePages istek işleme ara yazılımını çalıştırmadan önce. Ö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 UseStatusCodePagesetmek için:
- Ortamı üretim olarak ayarlayın.
-
webBuilder.UseStartup<StartupUseStatusCodePages>();içindeki yorumlarıProgram.cskaldırın. - Ana sayfadaki bağlantıları ana sayfada seçin.
Note
Durum kodu sayfaları ara yazılımı istisnaları 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.
UseStatusCodePages'ü örnek uygulamada test etmek için, içindeki açıklamaları webBuilder.UseStartup<StartupFormat>();'ten kaldırın.
Lambda ile UseStatusCodePages
Özel hata işleme ve yanıt yazma kodunu belirtmek için bir lambda ifadesi alan UseStatusCodePages'ın aşırı yükleme işlevini 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.
UseStatusCodePages'ü örnek uygulamada test etmek için, içindeki açıklamaları webBuilder.UseStartup<StartupStatusLambda>();'ten 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, ~ uygulamanın PathBase'si ile değiştirilir. 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.
UseStatusCodePages'ü örnek uygulamada test etmek için, içindeki açıklamaları webBuilder.UseStartup<StartupSCredirect>();'ten 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 yönlendirilebilmesi için UseStatusCodePagesWithReExecute'nin UseRouting'den önce yerleştirildiğinden emin olun.
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.
UseStatusCodePages'ü örnek uygulamada test etmek için, içindeki açıklamaları webBuilder.UseStartup<StartupSCreX>();'ten 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 fırlatabilir. Ü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 başlıkları
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 durumu 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 çöküyor.
- 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 Çekirdek 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 UseDeveloperExceptionPage yerleştirdiğinden, sonraki ara yazılımda özel durumlar yakalanır.
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 çalışma zamanı ortamları.
Geliştirici Özel Durum Sayfası, özel durum ve istek hakkında aşağıdaki bilgileri içerir:
- Yığın izleme
- Varsa sorgu dizesi parametreleri
- Tanımlama bilgileri, varsa
- Headers
Ö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 tekrar çalıştırılamaz. Şablon tarafından oluşturulan kod, isteği
/Erroriç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 HttpGetHTTP yöntemi öznitelikleriyle işaretlemeyin. Açık fiiller, bazı isteklerin yönteme 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";
}
}
}
Warning
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.
Warning
İstemcilereIExceptionHandlerFeature veya IExceptionHandlerPathFeature üzerinden hassas hata bilgileri sağlamayın. Hata sunma bir güvenlik riskidir.
Örnek uygulamada lambda özel durum işlemenin sonucunu görmek için ve ProdEnvironment önişlemci yönergelerini kullanın ve giriş sayfasında ErrorHandlerLambda seçeneğine tıklayın.
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 amacıyla, UseStatusCodePages yöntemi içinde Startup.Configure çağırın.
app.UseStatusCodePages();
İstek işleme ara yazılımından önce, çağrı UseStatusCodePages yapın (ö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 kodunu belirtmek için bir lambda ifadesi alan UseStatusCodePages'ın aşırı yükleme işlevini 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, ~ uygulamanın PathBase'si ile değiştirilir. 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 uygulamaPages/StatusCode.cshtml bölümüne 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.
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 yönlendirilebilmesi için UseStatusCodePagesWithReExecute'nin UseRouting'den önce yerleştirildiğinden emin olun.
Razor Sayfalar örneği için örnek uygulamaPages/StatusCode.cshtml bölümüne 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 ş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 segmenti 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 HttpGetHTTP yöntemi öznitelikleriyle işaretlemeyin. Açık fiiller, bazı isteklerin yönteme 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 başlıkları
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 çöküyor.
- 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. Sayfayı etkinleştirmek için Startup.Configure sayfasına kod ekleyin.
if (env.IsDevelopment())
{
app.UseDatabaseErrorPage();
}
UseDatabaseErrorPage Microsoft.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.
Tip
Ö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