ASP.NET Core Blazor uygulamalarında hataları işleme
Uyarı
ASP.NET Core'un bu sürümü artık desteklenmiyor. Daha fazla bilgi için bkz . .NET ve .NET Core Destek İlkesi. Geçerli sürüm için bu makalenin .NET 8 sürümüne bakın.
Bu makalede, işlenmeyen özel durumları yönetme Blazor ve hataları algılayıp işleyen uygulamalar geliştirme açıklanmaktadır.
Geliştirme sırasında ayrıntılı hatalar
Uygulama Blazor geliştirme sırasında düzgün çalışmadığında, uygulamadan ayrıntılı hata bilgileri almak sorunu gidermeye ve düzeltmeye yardımcı olur. Bir hata oluştuğunda uygulamalar ekranın Blazor alt kısmında açık sarı bir çubuk görüntüler:
- Geliştirme sırasında çubuk sizi özel durumu görebileceğiniz tarayıcı konsoluna yönlendirir.
- Üretimde, çubuk kullanıcıya bir hata oluştuğu konusunda uyarır ve tarayıcının yenilenmesini önerir.
Bu hata işleme deneyiminin kullanıcı arabirimi, proje şablonlarının Blazorbir parçasıdır. Proje şablonlarının Blazor tüm sürümleri, tarayıcılara hata kullanıcı arabiriminin içeriğini önbelleğe almaması için sinyal vermek için özniteliğini kullanmazdata-nosnippet
, ancak belgelerin tüm sürümleri Blazor özniteliğini uygular.
içinde Blazor Web App, bileşenindeki deneyimi özelleştirin MainLayout
. Ortam Etiketi Yardımcısı (örneğin, <environment include="Production">...</environment>
) bileşenlerde Razor desteklenmediğinden, aşağıdaki örnek farklı ortamlar IHostEnvironment için hata iletilerini yapılandırmak üzere ekler.
üst kısmında MainLayout.razor
:
@inject IHostEnvironment HostEnvironment
Hata kullanıcı arabirimi işaretlemesini Blazor oluşturun veya değiştirin:
<div id="blazor-error-ui" data-nosnippet>
@if (HostEnvironment.IsProduction())
{
<span>An error has occurred.</span>
}
else
{
<span>An unhandled exception occurred.</span>
}
<a href="" class="reload">Reload</a>
<a class="dismiss">🗙</a>
</div>
Bir Blazor Server uygulamada, dosyadaki deneyimi özelleştirin Pages/_Host.cshtml
. Aşağıdaki örnek, farklı ortamlar için hata iletilerini yapılandırmak için Ortam Etiketi Yardımcısı'nı kullanır.
Bir Blazor Server uygulamada, dosyadaki deneyimi özelleştirin Pages/_Layout.cshtml
. Aşağıdaki örnek, farklı ortamlar için hata iletilerini yapılandırmak için Ortam Etiketi Yardımcısı'nı kullanır.
Bir Blazor Server uygulamada, dosyadaki deneyimi özelleştirin Pages/_Host.cshtml
. Aşağıdaki örnek, farklı ortamlar için hata iletilerini yapılandırmak için Ortam Etiketi Yardımcısı'nı kullanır.
Hata kullanıcı arabirimi işaretlemesini Blazor oluşturun veya değiştirin:
<div id="blazor-error-ui" data-nosnippet>
<environment include="Staging,Production">
An error has occurred.
</environment>
<environment include="Development">
An unhandled exception occurred.
</environment>
<a href="" class="reload">Reload</a>
<a class="dismiss">🗙</a>
</div>
Bir Blazor WebAssembly uygulamada, dosyadaki deneyimi özelleştirin wwwroot/index.html
:
<div id="blazor-error-ui" data-nosnippet>
An unhandled error has occurred.
<a href="" class="reload">Reload</a>
<a class="dismiss">🗙</a>
</div>
blazor-error-ui
öğesi, uygulamanın otomatik olarak oluşturulan stil sayfasında CSS sınıfının stilinin blazor-error-ui
bulunması display: none
nedeniyle normalde gizlenir. Bir hata oluştuğunda, çerçeve öğesine uygulanır display: block
.
blazor-error-ui
öğesi normalde sitenin klasördeki stil sayfasında CSS sınıfının stilinin blazor-error-ui
bulunması display: none
nedeniyle gizlenirwwwroot/css
. Bir hata oluştuğunda, çerçeve öğesine uygulanır display: block
.
Ayrıntılı bağlantı hattı hataları
Bu bölüm bir Blazor Web Appbağlantı hattı üzerinde çalışan için geçerlidir.
Bu bölüm uygulamalar için Blazor Server geçerlidir.
İstemci tarafı hataları çağrı yığınını içermez ve hatanın nedeni hakkında ayrıntılı bilgi sağlamaz, ancak sunucu günlükleri bu tür bilgileri içerir. Geliştirme amacıyla hassas bağlantı hattı hata bilgileri, ayrıntılı hatalar etkinleştirilerek istemcinin kullanımına sunulabiliyor.
CircuitOptions.DetailedErrors seçeneğini true
olarak ayarlayın. Daha fazla bilgi ve örnek için bkz . ASP.NET Temel BlazorSignalR kılavuzu.
Ayarın CircuitOptions.DetailedErrors alternatifi, yapılandırma anahtarını true
uygulamanın Development
ortam ayarları dosyasında (appsettings.Development.json
olarak ayarlamaktırDetailedErrors
). Ayrıca, ayrıntılı SignalR günlük kaydı için sunucu tarafı günlüğünü (Microsoft.AspNetCore.SignalR
) Hata Ayıklama veya İzleme olarak ayarlayınSignalR.
appsettings.Development.json
:
{
"DetailedErrors": true,
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information",
"Microsoft.AspNetCore.SignalR": "Debug"
}
}
}
Yapılandırma DetailedErrors anahtarı, ortam sunucularındaStaging
Development
/veya yerel sisteminizde değeri olan ortam değişkenini true
kullanmaya ASPNETCORE_DETAILEDERRORS
da ayarlanabilir.true
Uyarı
Hata bilgilerini İnternet'te istemcilere ifşa etmekten her zaman kaçının; bu bir güvenlik riskidir.
Bileşen sunucu tarafı işleme için Razor ayrıntılı hatalar
Bu bölüm s için Blazor Web Appgeçerlidir.
RazorComponentsServiceOptions.DetailedErrors Bileşen sunucu tarafı işleme hataları hakkında ayrıntılı bilgi oluşturmayı denetlemek için Razor seçeneğini kullanın. Varsayılan değer şudur: false
.
Aşağıdaki örnek ayrıntılı hataları etkinleştirir:
builder.Services.AddRazorComponents(options =>
options.DetailedErrors = builder.Environment.IsDevelopment());
Uyarı
Yalnızca ortamdaki ayrıntılı hataları Development
etkinleştirin. Ayrıntılı hatalar, kötü amaçlı kullanıcıların bir saldırıda kullanabileceği uygulama hakkında hassas bilgiler içerebilir.
Yukarıdaki örnek, değerini tarafından IsDevelopmentdöndürülen değere DetailedErrors göre ayarlayarak bir güvenlik derecesi sağlar. Uygulama Development
ortamdayken olarak DetailedErrors ayarlanır true
. Üretim uygulamasını ortamdaki genel bir sunucuda Development
barındırmak mümkün olduğundan bu yaklaşım kusursuz değildir.
Geliştirici kodunda işlenmeyen özel durumları yönetme
Bir uygulamanın hatadan sonra devam etmesi için uygulamanın hata işleme mantığı olmalıdır. Bu makalenin sonraki bölümlerinde işlenmeyen özel durumların olası kaynakları açıklanmaktadır.
Üretimde çerçeve özel durum iletilerini işlemeyin veya kullanıcı arabiriminde izlemeleri yığınlamayın. Özel durum iletileri veya yığın izlemeleri işlenebilir:
- Hassas bilgileri son kullanıcılara ifşa etme.
- Kötü amaçlı bir kullanıcının uygulama, sunucu veya ağ güvenliğini tehlikeye atabilecek zayıflıkları bulmasına yardımcı olun.
Devreler için işlenmeyen özel durumlar
Bu bölüm, bir bağlantı hattı üzerinde çalışan sunucu tarafı uygulamaları için geçerlidir.
Razor sunucu etkileşiminin etkinleştirildiği bileşenler sunucuda durum bilgisi vardır. Kullanıcılar sunucudaki bileşenle etkileşim kurarken, bağlantı hattı olarak bilinen sunucuyla bağlantı kurar. Devre, etkin bileşen örneklerinin yanı sıra aşağıdakiler gibi diğer birçok durum yönünü barındırıyor:
- Bileşenlerin en son işlenen çıktısı.
- İstemci tarafı olayları tarafından tetiklenebilen geçerli olay işleme temsilcileri kümesi.
Bir kullanıcı uygulamayı birden çok tarayıcı sekmesinde açarsa, kullanıcı birden çok bağımsız devre oluşturur.
Blazor çoğu işlenmeyen özel durumları, oluştukları bağlantı hattı için önemli olarak kabul eder. İşlenmeyen bir özel durum nedeniyle bir bağlantı hattı sonlandırılırsa, kullanıcı yalnızca sayfayı yeniden yükleyerek yeni bir bağlantı hattı oluşturarak uygulamayla etkileşim kurmaya devam edebilir. Sonlandırılan devrenin dışında kalan ve diğer kullanıcıların veya diğer tarayıcı sekmelerinin devreleri olan devreler etkilenmez. Bu senaryo, kilitlenen bir masaüstü uygulamasına benzer. Kilitlenen uygulamanın yeniden başlatılması gerekir, ancak diğer uygulamalar etkilenmez.
Aşağıdaki nedenlerle işlenmeyen bir özel durum oluştuğunda çerçeve bir bağlantı hattını sonlandırır:
- İşlenmeyen bir özel durum genellikle devreyi tanımsız durumda bırakır.
- İşlenmeyen bir özel durumdan sonra uygulamanın normal işlemi garanti edilemez.
- Bağlantı hattı tanımlanmamış durumda devam ederse uygulamada güvenlik açıkları görüntülenebilir.
Genel özel durum işleme
Genel olarak özel durumları işleme yaklaşımları için aşağıdaki bölümlere bakın:
- Hata sınırları: Tüm Blazor uygulamalar için geçerlidir.
- Alternatif genel özel durum işleme: Genel etkileşimli işleme modunu benimseyen , Blazor WebAssemblyve Blazor Web Apps (8.0 veya üzeri) için Blazor Servergeçerlidir.
Hata sınırları
Hata sınırları , özel durumları işlemek için kullanışlı bir yaklaşım sağlar. Bileşen ErrorBoundary :
- Bir hata oluşmadığında alt içeriğini işler.
- Hata sınırındaki herhangi bir bileşen tarafından işlenmeyen bir özel durum oluştuğunda hata kullanıcı arabirimini işler.
Hata sınırı tanımlamak için, bir veya daha fazla bileşeni sarmak için bileşenini kullanın ErrorBoundary . Hata sınırı, sarmaladığı bileşenler tarafından oluşan işlenmeyen özel durumları yönetir.
<ErrorBoundary>
...
</ErrorBoundary>
Genel bir şekilde hata sınırı uygulamak için, uygulamanın ana düzeninin gövde içeriğinin çevresine sınırı ekleyin.
MainLayout.razor
içinde:
<article class="content px-4">
<ErrorBoundary>
@Body
</ErrorBoundary>
</article>
Hata sınırının yalnızca statik MainLayout
bir bileşene uygulandığı s'deBlazor Web App, sınır yalnızca statik sunucu tarafı işleme (statik SSR) sırasında etkindir. Sınır, yalnızca bileşen hiyerarşisinin daha aşağısındaki bir bileşen etkileşimli olduğundan etkinleştirilmez.
Bileşenin MainLayout
parametresi rastgele kod olan ve serileştirilemediği bir RenderFragment temsilci olduğundan, bileşene Body
etkileşimli işleme modu uygulanamaz. Bileşenin MainLayout
ve rest bileşenlerin bileşen hiyerarşisinin daha aşağısında etkileşime olanak tanımak için, uygulamanın genellikle App
bileşen olan kök bileşenindeki ve Routes
bileşen örneklerine HeadOutlet
etkileşimli işleme modunu uygulayarak genel bir etkileşimli işleme modunu benimsemesi gerekir. Aşağıdaki örnek, Etkileşimli Sunucu (InteractiveServer
) işleme modunu genel olarak benimser.
Components/App.razor
içinde:
<HeadOutlet @rendermode="InteractiveServer" />
...
<Routes @rendermode="InteractiveServer" />
Genel etkileşimi etkinleştirmemek isterseniz hata sınırını bileşen hiyerarşisinin daha aşağısına yerleştirin. Akılda tutulması gereken önemli kavramlar, hata sınırının nereye yerleştirildiğidir:
- Hata sınırının yerleştirildiği bileşen etkileşimli değilse, hata sınırı yalnızca statik SSR sırasında sunucuda etkinleştirilebilme özelliğine sahiptir. Örneğin, bir bileşen yaşam döngüsü yönteminde hata oluştuğunda sınır etkinleştirilebilir, ancak düğme tıklama işleyicisi tarafından atılan bir hata gibi, bileşen içindeki kullanıcı etkileşimi tarafından tetiklenen bir olay için etkinleştirilebilir.
- Hata sınırının yerleştirildiği bileşen etkileşimliyse, hata sınırı kaydırdığı etkileşimli bileşenler için etkinleştirilebilme özelliğine sahiptir.
Not
Bir uygulamanın istemci tarafı işlemesi (CSR) Blazor WebAssembly tamamen etkileşimli olduğundan, önceki önemli noktalar tek başına Blazor WebAssembly uygulamalarla ilgili değildir.
Ekli sayaç bileşeni tarafından oluşan bir özel durumun, etkileşimli işleme modunu benimseyen bileşendeki Home
bir hata sınırı tarafından yakalandığı aşağıdaki örneği göz önünde bulundurun.
EmbeddedCounter.razor
:
<h1>Embedded Counter</h1>
<p role="status">Current count: @currentCount</p>
<button class="btn btn-primary" @onclick="IncrementCount">Click me</button>
@code {
private int currentCount = 0;
private void IncrementCount()
{
currentCount++;
if (currentCount > 5)
{
throw new InvalidOperationException("Current count is too big!");
}
}
}
Home.razor
:
@page "/"
@rendermode InteractiveServer
<PageTitle>Home</PageTitle>
<h1>Home</h1>
<ErrorBoundary>
<EmbeddedCounter />
</ErrorBoundary>
Katıştırılmış sayaç bileşeni tarafından oluşan bir özel durumun bileşendeki Home
bir hata sınırı tarafından yakalandığı aşağıdaki örneği göz önünde bulundurun.
EmbeddedCounter.razor
:
<h1>Embedded Counter</h1>
<p role="status">Current count: @currentCount</p>
<button class="btn btn-primary" @onclick="IncrementCount">Click me</button>
@code {
private int currentCount = 0;
private void IncrementCount()
{
currentCount++;
if (currentCount > 5)
{
throw new InvalidOperationException("Current count is too big!");
}
}
}
Home.razor
:
@page "/"
<PageTitle>Home</PageTitle>
<h1>Home</h1>
<ErrorBoundary>
<EmbeddedCounter />
</ErrorBoundary>
İşlenmeyen özel durum beşin üzerinde bir currentCount
süre için oluşturulursa:
- Hata normal olarak günlüğe kaydedilir (
System.InvalidOperationException: Current count is too big!
). - Özel durum hata sınırı tarafından işlenir.
- Varsayılan hata kullanıcı arabirimi hata sınırı tarafından işlenir.
Bileşen, ErrorBoundary hata içeriği için CSS sınıfını blazor-error-boundary
kullanarak boş <div>
bir öğeyi işler. Varsayılan kullanıcı arabiriminin renkleri, metni ve simgesi, uygulamanın klasördeki stil sayfasında wwwroot
tanımlanır, bu nedenle hata kullanıcı arabirimini özelleştirebilirsiniz.
Varsayılan hata içeriğini değiştirmek için:
- özelliğindeki hata sınırının bileşenlerini sarmalar ChildContent .
- ErrorContent özelliğini hata içeriği olarak ayarlayın.
Aşağıdaki örnek bileşeni sarmalar EmbeddedCounter
ve özel hata içeriği sağlar:
<ErrorBoundary>
<ChildContent>
<EmbeddedCounter />
</ChildContent>
<ErrorContent>
<p class="errorUI">😈 A rotten gremlin got us. Sorry!</p>
</ErrorContent>
</ErrorBoundary>
Yukarıdaki örnekte, uygulamanın stil sayfası büyük olasılıkla içeriği stillendirmek için bir errorUI
CSS sınıfı içerir. Hata içeriği, blok düzeyi öğesi olmadan özelliğinden ErrorContent işlenir. Bölme () veya paragraf<p>
(<div>
) öğesi gibi blok düzeyinde bir öğe, hata içeriği işaretlemesini sarmalayabilir, ancak gerekli değildir.
İsteğe bağlı olarak, hata verilerini almak için bağlamını ErrorContent (@context
) kullanın:
<ErrorContent>
@context.HelpLink
</ErrorContent>
bağlamı ErrorContent da adlandırabilir. Aşağıdaki örnekte bağlam olarak adlandırılır exception
:
<ErrorContent Context="exception">
@exception.HelpLink
</ErrorContent>
Uyarı
Hata bilgilerini İnternet'te istemcilere ifşa etmekten her zaman kaçının; bu bir güvenlik riskidir.
Hata sınırı uygulamanın düzeninde tanımlanmışsa, hata oluştuktan sonra kullanıcının hangi sayfaya gidildiğine bakılmaksızın hata kullanıcı arabirimi görülür. Çoğu senaryoda hata sınırlarının kapsamını daraltmanızı öneririz. Bir hata sınırının kapsamını geniş kapsamlı olarak tanımlarsanız, hata sınırının Recover yöntemini çağırarak sonraki sayfa gezinti olaylarında hata olmayan bir duruma sıfırlayabilirsiniz.
MainLayout.razor
içinde:
- öznitelik yönergesi ErrorBoundary ile
@ref
bir başvuru yakalamak için bir alan ekleyin. - Yaşam döngüsü yönteminde
OnParameterSet
, kullanıcı farklı bir bileşene gittiği zaman hatayı temizlemek için ile Recover hata sınırında bir kurtarma tetikleyebilirsiniz.
...
<ErrorBoundary @ref="errorBoundary">
@Body
</ErrorBoundary>
...
@code {
private ErrorBoundary? errorBoundary;
protected override void OnParametersSet()
{
errorBoundary?.Recover();
}
}
Kurtarma işleminin yalnızca hatayı yeniden oluşturan bir bileşeni yeniden oluşturduğu sonsuz döngüden kaçınmak için işleme mantığını çağırmayın Recover . Yalnızca şu durumlarda arama Recover :
- Kullanıcı, bir yordamı yeniden denemek istediğini veya kullanıcı yeni bir bileşene gittiği zaman düğme seçme gibi bir kullanıcı arabirimi hareketi gerçekleştirir.
- Yürütülen ek mantık da özel durumu temizler. Bileşen yeniden başlatıldığında hata yinelenmez.
Aşağıdaki örnek, kullanıcının bir düğmeyle özel durumdan kurtarmasına izin verir:
<ErrorBoundary @ref="errorBoundary">
<ChildContent>
<EmbeddedCounter />
</ChildContent>
<ErrorContent>
<div class="alert alert-danger" role="alert">
<p class="fs-3 fw-bold">😈 A rotten gremlin got us. Sorry!</p>
<p>@context.HelpLink</p>
<button class="btn btn-info" @onclick="_ => errorBoundary?.Recover()">
Clear
</button>
</div>
</ErrorContent>
</ErrorBoundary>
@code {
private ErrorBoundary? errorBoundary;
}
Ayrıca geçersiz kılarak OnErrorAsyncözel işleme için alt sınıf ErrorBoundary oluşturabilirsiniz. Aşağıdaki örnek yalnızca hatayı günlüğe kaydeder, ancak istediğiniz hata işleme kodunu uygulayabilirsiniz. Kodunuz zaman uyumsuz bir CompletedTask görev bekliyorsa döndüren satırı kaldırabilirsiniz.
CustomErrorBoundary.razor
:
@inherits ErrorBoundary
@inject ILogger<CustomErrorBoundary> Logger
@if (CurrentException is null)
{
@ChildContent
}
else if (ErrorContent is not null)
{
@ErrorContent(CurrentException)
}
@code {
protected override Task OnErrorAsync(Exception ex)
{
Logger.LogError(ex, "😈 A rotten gremlin got us. Sorry!");
return Task.CompletedTask;
}
}
Yukarıdaki örnek bir sınıf olarak da uygulanabilir.
CustomErrorBoundary.cs
:
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Web;
namespace BlazorSample;
public class CustomErrorBoundary : ErrorBoundary
{
[Inject]
ILogger<CustomErrorBoundary> Logger { get; set; } = default!;
protected override Task OnErrorAsync(Exception ex)
{
Logger.LogError(ex, "😈 A rotten gremlin got us. Sorry!");
return Task.CompletedTask;
}
}
Bir bileşende kullanılan önceki uygulamalardan biri:
<CustomErrorBoundary>
...
</CustomErrorBoundary>
Alternatif genel özel durum işleme
Bu bölümde açıklanan yaklaşım, genel etkileşimli işleme modunu (, veya ) benimseyen , Blazor WebAssemblyve Blazor Web Apps için geçerlidirBlazor Server.InteractiveAuto
InteractiveWebAssembly
InteractiveServer
Yaklaşım, işleme modu sınırları boyunca veya statik SSR'yi benimseyen bileşenlerle çalışmayan bir CascadingValue
/CascadingParameter
öğesine bağlı olduğundan, yaklaşım sayfa başına/bileşen işleme modlarını veya statik sunucu tarafı işlemeyi (statik SSR) benimseyenlerle çalışmaz.Blazor Web App
Hata sınırlarını (ErrorBoundary) kullanmanın bir alternatifi, özel bir hata bileşenini alt bileşenlere geçirmektir.CascadingValue
Eklenen hizmeti veya özel günlükçü uygulamasını kullanmak yerine bir bileşeni kullanmanın avantajlarından biri, basamaklı bir bileşenin bir hata oluştuğunda içeriği işleyip CSS stilleri uygulayabilmesidir.
Aşağıdaki ProcessError
bileşen örneği yalnızca hataları günlüğe kaydeder, ancak bileşenin yöntemleri, birden çok hata işleme yönteminin kullanılması da dahil olmak üzere uygulama tarafından gerekli olan herhangi bir şekilde hataları işleyebilir.
ProcessError.razor
:
@inject ILogger<ProcessError> Logger
<CascadingValue Value="this">
@ChildContent
</CascadingValue>
@code {
[Parameter]
public RenderFragment? ChildContent { get; set; }
public void LogError(Exception ex)
{
Logger.LogError("ProcessError.LogError: {Type} Message: {Message}",
ex.GetType(), ex.Message);
// Call StateHasChanged if LogError directly participates in
// rendering. If LogError only logs or records the error,
// there's no need to call StateHasChanged.
//StateHasChanged();
}
}
Not
hakkında RenderFragmentdaha fazla bilgi için bkz . ASP.NET Core Razor bileşenleri.
bu yaklaşımı bir Blazor Web Appiçinde kullanırken, bileşeni açın Routes
ve bileşeni (<Router>...</Router>
) bileşenle sarmalar Router ProcessError
. Bu, bileşenin, bileşenin ProcessError
olarak alındığı uygulamanın herhangi bir CascadingParameter
bileşenine art arda inmesine ProcessError
izin verir.
Routes.razor
içinde:
<ProcessError>
<Router ...>
...
</Router>
</ProcessError>
Bir veya uygulamasında bu yaklaşımı Blazor Server kullanırken, bileşeni açınApp
, bileşeni (<Router>...</Router>
) bileşenle sarmalar Router ProcessError
.Blazor WebAssembly Bu, bileşenin, bileşenin ProcessError
olarak alındığı uygulamanın herhangi bir CascadingParameter
bileşenine art arda inmesine ProcessError
izin verir.
App.razor
içinde:
<ProcessError>
<Router ...>
...
</Router>
</ProcessError>
Bir bileşendeki hataları işlemek için:
Bileşeni blokta
@code
olarakCascadingParameter
belirleyinProcessError
. Proje şablonunu temel alan Blazor bir uygulamadaki örnekCounter
bileşene aşağıdakiProcessError
özelliği ekleyin:[CascadingParameter] public ProcessError? ProcessError { get; set; }
Uygun bir özel durum türüne sahip herhangi bir
catch
blokta hata işleme yöntemini çağır. ÖrnekProcessError
bileşen yalnızca tekLogError
bir yöntem sunar, ancak hata işleme bileşeni uygulama genelinde alternatif hata işleme gereksinimlerini karşılamak için herhangi bir sayıda hata işleme yöntemi sağlayabilir. AşağıdakiCounter
bileşen@code
bloğu örneği basamaklı parametresiniProcessError
içerir ve sayı beşten büyük olduğunda günlüğe kaydetme için bir özel durum yakalar:@code { private int currentCount = 0; [CascadingParameter] public ProcessError? ProcessError { get; set; } private void IncrementCount() { try { currentCount++; if (currentCount > 5) { throw new InvalidOperationException("Current count is over five!"); } } catch (Exception ex) { ProcessError?.LogError(ex); } } }
Günlüğe kaydedilen hata:
fail: {COMPONENT NAMESPACE}.ProcessError[0]
ProcessError.LogError: System.InvalidOperationException Message: Current count is over five!
LogError
Yöntem, özel bir hata iletisi çubuğu gösterme veya işlenen öğelerin CSS stillerini değiştirme gibi işlemeye doğrudan katılıyorsa, kullanıcı arabirimini yeniden oluşturmak için yöntemin LogError
sonunda çağrısı StateHasChanged
yapın.
Bu bölümdeki yaklaşımlar bir try-catch
deyimle ilgili hataları işlediğinden, bir hata oluştuğunda ve bağlantı hattı canlı kaldığında uygulamanın SignalR istemci ve sunucu arasındaki bağlantısı kopmuyor. İşlenmeyen diğer özel durumlar bir bağlantı hattı için önemli olmaya devam eder. Daha fazla bilgi için, devrenin işlenmeyen özel durumlara nasıl tepki vermesine ilişkin bölüme bakın.
Uygulama, hataları merkezi bir şekilde işlemek için bir hata işleme bileşenini basamaklı değer olarak kullanabilir.
Aşağıdaki ProcessError
bileşen kendisini alt bileşenlere geçirir CascadingValue
. Aşağıdaki örnek yalnızca hatayı günlüğe kaydeder, ancak bileşenin yöntemleri, birden çok hata işleme yönteminin kullanılması da dahil olmak üzere uygulamanın gerektirdiği herhangi bir şekilde hataları işleyebilir. Eklenen hizmeti veya özel günlükçü uygulamasını kullanmak yerine bir bileşeni kullanmanın avantajlarından biri, basamaklı bir bileşenin bir hata oluştuğunda içeriği işleyip CSS stilleri uygulayabilmesidir.
ProcessError.razor
:
@using Microsoft.Extensions.Logging
@inject ILogger<ProcessError> Logger
<CascadingValue Value="this">
@ChildContent
</CascadingValue>
@code {
[Parameter]
public RenderFragment ChildContent { get; set; }
public void LogError(Exception ex)
{
Logger.LogError("ProcessError.LogError: {Type} Message: {Message}",
ex.GetType(), ex.Message);
}
}
Not
hakkında RenderFragmentdaha fazla bilgi için bkz . ASP.NET Core Razor bileşenleri.
BileşendeApp
, bileşeni bileşenle birlikte sarmalar ProcessError
Router. Bu, bileşenin, bileşenin ProcessError
olarak alındığı uygulamanın herhangi bir CascadingParameter
bileşenine art arda inmesine ProcessError
izin verir.
App.razor
:
<ProcessError>
<Router ...>
...
</Router>
</ProcessError>
Bir bileşendeki hataları işlemek için:
ProcessError
Bileşeni bloğunda@code
olarakCascadingParameter
belirleyin:[CascadingParameter] public ProcessError ProcessError { get; set; }
Uygun bir özel durum türüne sahip herhangi bir
catch
blokta hata işleme yöntemini çağır. ÖrnekProcessError
bileşen yalnızca tekLogError
bir yöntem sunar, ancak hata işleme bileşeni uygulama genelinde alternatif hata işleme gereksinimlerini karşılamak için herhangi bir sayıda hata işleme yöntemi sağlayabilir.try { ... } catch (Exception ex) { ProcessError.LogError(ex); }
Yukarıdaki örnek ProcessError
bileşeni ve LogError
yöntemi kullanarak tarayıcının geliştirici araçları konsolu kapana kısılmış, günlüğe kaydedilen hatayı gösterir:
fail: {COMPONENT NAMESPACE}.Shared.ProcessError[0]
ProcessError.LogError: System.NullReferenceException Message: Object reference not set to an instance of an object.
LogError
Yöntem, özel bir hata iletisi çubuğu gösterme veya işlenen öğelerin CSS stillerini değiştirme gibi işlemeye doğrudan katılıyorsa, kullanıcı arabirimini yeniden oluşturmak için yöntemin LogError
sonunda çağrısı StateHasChanged
yapın.
Bu bölümdeki yaklaşımlar bir try-catch
deyimle ilgili hataları işlediğinden, bir Blazor hata oluştuğunda ve bağlantı hattı canlı kaldığında uygulamanın SignalR istemci ile sunucu arasındaki bağlantısı kopmuyor. İşlenmeyen özel durumlar bir bağlantı hattı için önemlidir. Daha fazla bilgi için, devrenin işlenmeyen özel durumlara nasıl tepki vermesine ilişkin bölüme bakın.
Kalıcı sağlayıcıyla hataları günlüğe kaydetme
İşlenmeyen bir özel durum oluşursa, özel durum hizmet kapsayıcısında yapılandırılan örneklere ILogger kaydedilir. Blazor uygulamalar, Konsol Günlüğü Sağlayıcısı ile konsol çıkışını günlüğe kaydeder. Günlük boyutunu ve günlük döndürmeyi yöneten bir sağlayıcıyla sunucudaki bir konuma (veya istemci tarafı uygulamalar için arka uç web API'sine) günlük kaydı yapmayı göz önünde bulundurun. Alternatif olarak, uygulama Azure Uygulaması lication Insights (Azure İzleyici) gibi bir Uygulama Performansı Yönetimi (APM) hizmeti kullanabilir.
Not
İstemci tarafı uygulamalarını desteklemek için yerel Application Insights özellikleri ve Google Analytics için yerel Blazor çerçeve desteği, bu teknolojilerin gelecek sürümlerinde kullanılabilir hale gelebilir. Daha fazla bilgi için bkz . WASM İstemci Tarafında App Insights Blazor Desteği (microsoft/ApplicationInsights-dotnet #2143) ve Web analizi ve tanılama (topluluk uygulamalarına bağlantılar içerir) (dotnet/aspnetcore #5461). Bu arada, istemci tarafı bir uygulama, hataları doğrudan istemci tarafı uygulamasından Application Insights'a günlüğe kaydetmek için birlikte çalışma ile JS Application Insights JavaScript SDK'sını kullanabilir.
Bir bağlantı hattı üzerinden çalışan bir Blazor uygulamada geliştirme sırasında uygulama genellikle hata ayıklamaya yardımcı olmak için özel durumların tüm ayrıntılarını tarayıcının konsoluna gönderir. Üretimde, ayrıntılı hatalar istemcilere gönderilmez, ancak özel durumun tüm ayrıntıları sunucuda günlüğe kaydedilir.
Hangi olayların günlüğe kaydedileceğine ve günlüğe kaydedilen olayların önem düzeyine karar vermeniz gerekir. Saldırgan kullanıcılar hataları kasıtlı olarak tetikleyebilir. Örneğin, ürün ayrıntılarını görüntüleyen bir bileşenin URL'sinde bilinmeyen ProductId
bir hatanın bulunduğu bir hatayı günlüğe kaydetmeyin. Tüm hatalar günlüğe kaydetme olayı olarak değerlendirilmemelidir.
Daha fazla bilgi için aşağıdaki makaleleri inceleyin:
- ASP.NET Core Blazor günlüğü
- ASP.NET Core'daki hataları işleme‡
- ASP.NET Core ile web API'leri oluşturma
‡için web API arka uç uygulamaları olan sunucu tarafı Blazor uygulamalar ve diğer sunucu tarafı ASP.NET Core uygulamaları için Blazorgeçerlidir. İstemci tarafı uygulamaları, istemcideki hata bilgilerini yakalayıp bir web API'sine gönderebilir ve bu da hata bilgilerini kalıcı bir günlük sağlayıcısına günlüğe kaydeder.
İşlenmeyen bir özel durum oluşursa, özel durum hizmet kapsayıcısında yapılandırılan örneklere ILogger kaydedilir. Blazor uygulamalar, Konsol Günlüğü Sağlayıcısı ile konsol çıkışını günlüğe kaydeder. Günlük boyutu yönetimi ve günlük döndürmesi olan bir günlük sağlayıcısı kullanan bir arka uç web API'sine hata bilgileri göndererek sunucuda daha kalıcı bir konuma oturum açmayı göz önünde bulundurun. Alternatif olarak, arka uç web API'si uygulaması istemcilerden aldığı hata bilgilerini kaydetmek için Azure Uygulaması lication Insights (Azure İzleyici)† gibi bir Uygulama Performansı Yönetimi (APM) hizmetini kullanabilir.
Hangi olayların günlüğe kaydedileceğine ve günlüğe kaydedilen olayların önem düzeyine karar vermeniz gerekir. Saldırgan kullanıcılar hataları kasıtlı olarak tetikleyebilir. Örneğin, ürün ayrıntılarını görüntüleyen bir bileşenin URL'sinde bilinmeyen ProductId
bir hatanın bulunduğu bir hatayı günlüğe kaydetmeyin. Tüm hatalar günlüğe kaydetme olayı olarak değerlendirilmemelidir.
Daha fazla bilgi için aşağıdaki makaleleri inceleyin:
- ASP.NET Core Blazor günlüğü
- ASP.NET Core'daki hataları işleme‡
- ASP.NET Core ile web API'leri oluşturma
†İstek tarafı uygulamaları ve Google Analytics için yerel Blazor çerçeve desteğini desteklemek için †Native Application Insights özellikleri, bu teknolojilerin gelecek sürümlerinde kullanılabilir hale gelebilir. Daha fazla bilgi için bkz . WASM İstemci Tarafında App Insights Blazor Desteği (microsoft/ApplicationInsights-dotnet #2143) ve Web analizi ve tanılama (topluluk uygulamalarına bağlantılar içerir) (dotnet/aspnetcore #5461). Bu arada, istemci tarafı bir uygulama, hataları doğrudan istemci tarafı uygulamasından Application Insights'a günlüğe kaydetmek için birlikte çalışma ile JS Application Insights JavaScript SDK'sını kullanabilir.
‡Uygulamalar için web API arka uç uygulamaları olan sunucu tarafı ASP.NET Core uygulamaları için Blazor geçerlidir. İstemci tarafı uygulamalar yakalanıp hata bilgilerini bir web API'sine gönderir ve hata bilgilerini kalıcı bir günlük sağlayıcısına kaydeder.
Hataların oluşabileceği yerler
Çerçeve ve uygulama kodu, bu makalenin aşağıdaki bölümlerinde daha ayrıntılı olarak açıklanan aşağıdaki konumlardan herhangi birinde işlenmeyen özel durumlar tetikleyebilir:
Bileşen örneği oluşturma
Bir bileşenin örneğini oluşturduğunda Blazor :
- Bileşenin oluşturucusunun çağrılır.
- yönergesi veya özniteliği aracılığıyla
@inject
bileşenin oluşturucusunun sağladığı DI hizmetlerinin[Inject]
oluşturucuları çağrılır.
Yürütülen bir oluşturucuda veya herhangi [Inject]
bir özellik için ayarlayıcıda oluşan bir hata işlenmeyen bir özel durumla sonuçlanır ve çerçevenin bileşenin örneğini oluşturmasını durdurur. Uygulama bir bağlantı hattı üzerinden çalışıyorsa devre başarısız olur. Oluşturucu mantığı özel durumlar oluşturabilecekse, uygulama hata işleme ve günlüğe kaydetme ile bir try-catch
deyimi kullanarak özel durumları yakalamalıdır.
Yaşam döngüsü yöntemleri
Bir bileşenin ömrü boyunca yaşam Blazor döngüsü yöntemlerini çağırır. Herhangi bir yaşam döngüsü yöntemi zaman uyumlu veya zaman uyumsuz bir özel durum oluşturursa, özel durum bir bağlantı hattı için önemli olur. Bileşenlerin yaşam döngüsü yöntemlerindeki hatalarla başa çıkabilmek için hata işleme mantığı ekleyin.
Aşağıdaki örnekte OnParametersSetAsync bir ürünü almak için bir yöntemi çağırır:
- yönteminde
ProductRepository.GetProductByIdAsync
oluşan bir özel durum birtry-catch
deyimi tarafından işlenir. catch
Blok yürütülürken:loadFailed
olarak ayarlanırtrue
ve kullanıcıya bir hata iletisi görüntülemek için kullanılır.- Hata günlüğe kaydedilir.
@page "/product-details/{ProductId:int?}"
@inject ILogger<ProductDetails> Logger
@inject IProductRepository Product
<PageTitle>Product Details</PageTitle>
<h1>Product Details Example</h1>
@if (details != null)
{
<h2>@details.ProductName</h2>
<p>
@details.Description
<a href="@details.Url">Company Link</a>
</p>
}
else if (loadFailed)
{
<h1>Sorry, we could not load this product due to an error.</h1>
}
else
{
<h1>Loading...</h1>
}
@code {
private ProductDetail? details;
private bool loadFailed;
[Parameter]
public int ProductId { get; set; }
protected override async Task OnParametersSetAsync()
{
try
{
loadFailed = false;
// Reset details to null to display the loading indicator
details = null;
details = await Product.GetProductByIdAsync(ProductId);
}
catch (Exception ex)
{
loadFailed = true;
Logger.LogWarning(ex, "Failed to load product {ProductId}", ProductId);
}
}
public class ProductDetail
{
public string? ProductName { get; set; }
public string? Description { get; set; }
public string? Url { get; set; }
}
/*
* Register the service in Program.cs:
* using static BlazorSample.Components.Pages.ProductDetails;
* builder.Services.AddScoped<IProductRepository, ProductRepository>();
*/
public interface IProductRepository
{
public Task<ProductDetail> GetProductByIdAsync(int id);
}
public class ProductRepository : IProductRepository
{
public Task<ProductDetail> GetProductByIdAsync(int id)
{
return Task.FromResult(
new ProductDetail()
{
ProductName = "Flowbee ",
Description = "The Revolutionary Haircutting System You've Come to Love!",
Url = "https://flowbee.com/"
});
}
}
}
@page "/product-details/{ProductId:int?}"
@inject ILogger<ProductDetails> Logger
@inject IProductRepository Product
<PageTitle>Product Details</PageTitle>
<h1>Product Details Example</h1>
@if (details != null)
{
<h2>@details.ProductName</h2>
<p>
@details.Description
<a href="@details.Url">Company Link</a>
</p>
}
else if (loadFailed)
{
<h1>Sorry, we could not load this product due to an error.</h1>
}
else
{
<h1>Loading...</h1>
}
@code {
private ProductDetail? details;
private bool loadFailed;
[Parameter]
public int ProductId { get; set; }
protected override async Task OnParametersSetAsync()
{
try
{
loadFailed = false;
// Reset details to null to display the loading indicator
details = null;
details = await Product.GetProductByIdAsync(ProductId);
}
catch (Exception ex)
{
loadFailed = true;
Logger.LogWarning(ex, "Failed to load product {ProductId}", ProductId);
}
}
public class ProductDetail
{
public string? ProductName { get; set; }
public string? Description { get; set; }
public string? Url { get; set; }
}
/*
* Register the service in Program.cs:
* using static BlazorSample.Components.Pages.ProductDetails;
* builder.Services.AddScoped<IProductRepository, ProductRepository>();
*/
public interface IProductRepository
{
public Task<ProductDetail> GetProductByIdAsync(int id);
}
public class ProductRepository : IProductRepository
{
public Task<ProductDetail> GetProductByIdAsync(int id)
{
return Task.FromResult(
new ProductDetail()
{
ProductName = "Flowbee ",
Description = "The Revolutionary Haircutting System You've Come to Love!",
Url = "https://flowbee.com/"
});
}
}
}
@page "/product-details/{ProductId:int}"
@using Microsoft.Extensions.Logging
@inject ILogger<ProductDetails> Logger
@inject IProductRepository ProductRepository
@if (details != null)
{
<h1>@details.ProductName</h1>
<p>@details.Description</p>
}
else if (loadFailed)
{
<h1>Sorry, we could not load this product due to an error.</h1>
}
else
{
<h1>Loading...</h1>
}
@code {
private ProductDetail? details;
private bool loadFailed;
[Parameter]
public int ProductId { get; set; }
protected override async Task OnParametersSetAsync()
{
try
{
loadFailed = false;
// Reset details to null to display the loading indicator
details = null;
details = await ProductRepository.GetProductByIdAsync(ProductId);
}
catch (Exception ex)
{
loadFailed = true;
Logger.LogWarning(ex, "Failed to load product {ProductId}", ProductId);
}
}
public class ProductDetail
{
public string? ProductName { get; set; }
public string? Description { get; set; }
}
public interface IProductRepository
{
public Task<ProductDetail> GetProductByIdAsync(int id);
}
}
@page "/product-details/{ProductId:int}"
@using Microsoft.Extensions.Logging
@inject ILogger<ProductDetails> Logger
@inject IProductRepository ProductRepository
@if (details != null)
{
<h1>@details.ProductName</h1>
<p>@details.Description</p>
}
else if (loadFailed)
{
<h1>Sorry, we could not load this product due to an error.</h1>
}
else
{
<h1>Loading...</h1>
}
@code {
private ProductDetail? details;
private bool loadFailed;
[Parameter]
public int ProductId { get; set; }
protected override async Task OnParametersSetAsync()
{
try
{
loadFailed = false;
// Reset details to null to display the loading indicator
details = null;
details = await ProductRepository.GetProductByIdAsync(ProductId);
}
catch (Exception ex)
{
loadFailed = true;
Logger.LogWarning(ex, "Failed to load product {ProductId}", ProductId);
}
}
public class ProductDetail
{
public string? ProductName { get; set; }
public string? Description { get; set; }
}
public interface IProductRepository
{
public Task<ProductDetail> GetProductByIdAsync(int id);
}
}
@page "/product-details/{ProductId:int}"
@using Microsoft.Extensions.Logging
@inject ILogger<ProductDetails> Logger
@inject IProductRepository ProductRepository
@if (details != null)
{
<h1>@details.ProductName</h1>
<p>@details.Description</p>
}
else if (loadFailed)
{
<h1>Sorry, we could not load this product due to an error.</h1>
}
else
{
<h1>Loading...</h1>
}
@code {
private ProductDetail details;
private bool loadFailed;
[Parameter]
public int ProductId { get; set; }
protected override async Task OnParametersSetAsync()
{
try
{
loadFailed = false;
// Reset details to null to display the loading indicator
details = null;
details = await ProductRepository.GetProductByIdAsync(ProductId);
}
catch (Exception ex)
{
loadFailed = true;
Logger.LogWarning(ex, "Failed to load product {ProductId}", ProductId);
}
}
public class ProductDetail
{
public string ProductName { get; set; }
public string Description { get; set; }
}
public interface IProductRepository
{
public Task<ProductDetail> GetProductByIdAsync(int id);
}
}
@page "/product-details/{ProductId:int}"
@using Microsoft.Extensions.Logging
@inject ILogger<ProductDetails> Logger
@inject IProductRepository ProductRepository
@if (details != null)
{
<h1>@details.ProductName</h1>
<p>@details.Description</p>
}
else if (loadFailed)
{
<h1>Sorry, we could not load this product due to an error.</h1>
}
else
{
<h1>Loading...</h1>
}
@code {
private ProductDetail details;
private bool loadFailed;
[Parameter]
public int ProductId { get; set; }
protected override async Task OnParametersSetAsync()
{
try
{
loadFailed = false;
// Reset details to null to display the loading indicator
details = null;
details = await ProductRepository.GetProductByIdAsync(ProductId);
}
catch (Exception ex)
{
loadFailed = true;
Logger.LogWarning(ex, "Failed to load product {ProductId}", ProductId);
}
}
public class ProductDetail
{
public string ProductName { get; set; }
public string Description { get; set; }
}
public interface IProductRepository
{
public Task<ProductDetail> GetProductByIdAsync(int id);
}
}
İşleme mantığı
Bir Razor bileşen dosyasındaki (.razor
) bildirim temelli işaretleme, adlı BuildRenderTreebir C# yönteminde derlenmiştir. Bir bileşen işlendiğinde, BuildRenderTree işlenen bileşenin öğelerini, metnini ve alt bileşenlerini açıklayan bir veri yapısı yürütür ve oluşturur.
İşleme mantığı özel durum oluşturabilir. Bu senaryonun bir örneği, değerlendirildiğinde @someObject.PropertyName
ancak @someObject
olduğunda null
oluşur. Bir devre üzerinde çalışan uygulamalar için Blazor , işleme mantığı tarafından oluşan işlenmeyen bir özel durum, uygulamanın devresinde önemli olur.
İşleme mantığını önlemek NullReferenceException için, üyelerine erişmeden önce bir null
nesneyi denetleyin. Aşağıdaki örnekte ise person.Address
özelliklere person.Address
null
erişilenmez:
@if (person.Address != null)
{
<div>@person.Address.Line1</div>
<div>@person.Address.Line2</div>
<div>@person.Address.City</div>
<div>@person.Address.Country</div>
}
Yukarıdaki kod bunun person
olmadığını null
varsayar. Genellikle kodun yapısı, bileşenin işlendiği sırada bir nesnenin var olduğunu garanti eder. Bu gibi durumlarda, işleme mantığını denetlemek null
gerekmez. Önceki örnekte, person
aşağıdaki örnekte gösterildiği gibi bileşen örneği oluşturulurken oluşturulduğu için var person
olacağı garanti edilebilir:
@code {
private Person person = new();
...
}
Olay işleyicileri
İstemci tarafı kodu, aşağıdakiler kullanılarak olay işleyicileri oluşturulduğunda C# kodunun çağrılarını tetikler:
@onclick
@onchange
- Diğer
@on...
öznitelikler @bind
Olay işleyici kodu bu senaryolarda işlenmeyen bir özel durum oluşturabilir.
Uygulama dış nedenlerle başarısız olabilecek kodu çağırırsa, hata işleme ve günlüğe kaydetme özelliğine sahip bir try-catch
deyimi kullanarak özel durumları yakalayın.
Bir olay işleyicisi, geliştirici kodu tarafından tuzağa düşürülmeyen ve işlenmeyen bir özel durum oluşturursa (örneğin, veritabanı sorgusu başarısız oluyorsa):
- Çerçeve özel durumu günlüğe kaydeder.
- Bir bağlantı hattı üzerinden çalışan bir Blazor uygulamada, özel durum uygulamanın bağlantı hattı için önemli olur.
Bileşen elden çıkarma
Kullanıcı başka bir sayfaya gitmesinden dolayı bir bileşen kullanıcı arabiriminden kaldırılabilir. Uygulayan System.IDisposable bir bileşen kullanıcı arabiriminden kaldırıldığında, çerçeve bileşenin Dispose yöntemini çağırır.
Bileşenin Dispose
yöntemi bir bağlantı hattı üzerinde çalışan bir Blazor uygulamada işlenmeyen bir özel durum oluşturursa, özel durum uygulamanın bağlantı hattı için önemli olur.
Atma mantığı özel durumlar oluşturabilecekse, uygulamanın hata işleme ve günlüğe kaydetme ile bir try-catch
deyimi kullanarak özel durumları yakalaması gerekir.
Bileşenin elden çıkarılması hakkında daha fazla bilgi için bkz . ASP.NET Core Razor bileşen yaşam döngüsü.
JavaScript ile birlikte çalışma
IJSRuntime , çerçeve tarafından Blazor kaydedilir. IJSRuntime.InvokeAsync .NET kodunun kullanıcının tarayıcısında JavaScript (JS) çalışma zamanına zaman uyumsuz çağrılar yapmasına izin verir.
aşağıdaki koşullar ile InvokeAsynchata işleme için geçerlidir:
- Çağrısı InvokeAsync zaman uyumlu olarak başarısız olursa bir .NET özel durumu oluşur. InvokeAsync Örneğin, sağlanan bağımsız değişkenler serileştirilemediğinden çağrısı başarısız olabilir. Geliştirici kodu özel durumu yakalamalıdır. Bir olay işleyicisindeki veya bileşen yaşam döngüsü yöntemindeki uygulama kodu bir bağlantı hattı üzerinde çalışan bir Blazor uygulamada özel durumu işlemezse, sonuçta elde edilen özel durum uygulamanın devresinde önemli olur.
- Çağrısı InvokeAsync zaman uyumsuz olarak başarısız olursa , .NET Task başarısız olur. InvokeAsync Örneğin, -side kodu bir özel durum oluşturacağından veya olarak
rejected
tamamlanmış birPromise
döndürdüğünden JSçağrısı başarısız olabilir. Geliştirici kodu özel durumu yakalamalıdır. işleciniawait
kullanıyorsanız, yöntem çağrısını hata işleme ve günlüğe kaydetme ile birtry-catch
deyimde sarmalamanız gerekir. Aksi takdirde, bir bağlantı hattı üzerinden çalışan bir Blazor uygulamada başarısız olan kod, uygulamanın bağlantı hattında önemli olan işlenmemiş bir özel durumla sonuçlanabilir. - çağrısının InvokeAsync belirli bir süre içinde tamamlanması gerekir, aksi halde arama zaman aşımına ulmalıdır. Varsayılan zaman aşımı süresi bir dakikadır. Zaman aşımı, kodu hiçbir zaman tamamlama iletisi göndermeden ağ bağlantısı veya JS kod kaybına karşı korur. Arama zaman aşımına ularsa, sonuç System.Threading.Tasks bir OperationCanceledExceptionile başarısız olur. Özel durumu günlüğe kaydetme ile yakalayın ve işleyin.
Benzer şekilde, JS kod özniteliği tarafından belirtilen .NET yöntemlerine [JSInvokable]
çağrı başlatabilir. Bu .NET yöntemleri işlenmeyen bir özel durum oluşturursa:
- Bir bağlantı hattı üzerinden çalışan bir Blazor uygulamada, özel durum uygulamanın bağlantı hattı için önemli olarak kabul edilir.
- JS-side
Promise
reddedilir.
.NET tarafında veya JS yöntem çağrısının tarafında hata işleme kodunu kullanma seçeneğiniz vardır.
Daha fazla bilgi için aşağıdaki makaleleri inceleyin:
- ASP.NET Core Blazor'da .NET yöntemlerinden JavaScript işlevlerini çağırma
- ASP.NET Core Blazor'da JavaScript işlevlerinden .NET yöntemlerini çağırma
Ön Kayıt
Razor bileşenleri varsayılan olarak önceden oluşturulur, böylece işlenen HTML işaretlemeleri kullanıcının ilk HTTP isteğinin bir parçası olarak döndürülür.
Devre üzerinden çalışan bir Blazor uygulamada, ön kayıt şu şekilde çalışır:
- Aynı sayfanın parçası olan önceden oluşturulmuş tüm bileşenler için yeni bir bağlantı hattı oluşturma.
- İlk HTML oluşturuluyor.
- Kullanıcının tarayıcısı aynı sunucuya yeniden bağlantı kurana SignalR kadar bağlantı hattını olarak
disconnected
ele alır. Bağlantı kurulduğunda, bağlantı hattındaki etkileşim sürdürülür ve bileşenlerin HTML işaretlemesi güncelleştirilir.
Önceden oluşturulmuş istemci tarafı bileşenleri için, ön kayıt şu şekilde çalışır:
- Aynı sayfanın parçası olan önceden oluşturulmuş tüm bileşenler için sunucuda ilk HTML oluşturuluyor.
- Tarayıcı, uygulamanın derlenmiş kodunu ve .NET çalışma zamanını (henüz yüklenmemişse) arka plana yükledikten sonra bileşeni istemcide etkileşimli hale getirme.
Bir bileşen, örneğin bir yaşam döngüsü yöntemi veya işleme mantığı sırasında ön kayıt sırasında işlenmeyen bir özel durum oluşturursa:
- Bir bağlantı hattı üzerinde çalışan bir Blazor uygulamada, özel durum devre için önemlidir. Önceden oluşturulmuş istemci tarafı bileşenleri için özel durum, bileşenin işlenmesini engeller.
- Özel durum çağrısı yığınından ComponentTagHelperoluşturulur.
Prerendering başarısız olduğunda normal koşullarda, çalışan bir bileşen işlenemediğinden bileşeni derlemeye ve işlemeye devam etmek mantıklı değildir.
Ön kayıt sırasında oluşabilecek hataları tolere etmek için hata işleme mantığı özel durumlar oluşturabilecek bir bileşenin içine yerleştirilmelidir. Hata işleme ve günlüğe kaydetme ile deyimleri kullanın try-catch
. deyimini ComponentTagHelper sarmalamak try-catch
yerine hata işleme mantığını tarafından işlenen bileşene ComponentTagHelperyerleştirin.
Gelişmiş senaryolar
Özyinelemeli işleme
Bileşenler özyinelemeli olarak iç içe yerleştirilebilir. Bu, özyinelemeli veri yapılarını temsil etmek için kullanışlıdır. Örneğin, bir TreeNode
bileşen düğümün alt öğelerinin her biri için daha fazla TreeNode
bileşen işleyebilir.
Özyinelemeli olarak işlenirken, sonsuz özyinelemeyle sonuçlayan kodlama desenlerinden kaçının:
- Döngü içeren bir veri yapısını yinelemeli olarak işlemeyin. Örneğin, alt öğeleri kendisini içeren bir ağaç düğümü oluşturmayın.
- Döngü içeren bir düzen zinciri oluşturmayın. Örneğin, düzeni kendisinde olan bir düzen oluşturmayın.
- Son kullanıcının kötü amaçlı veri girişi veya JavaScript birlikte çalışma çağrıları aracılığıyla özyineleme sabitlerini (kuralları) ihlal etmelerine izin verme.
İşleme sırasında sonsuz döngüler:
- İşleme işleminin sonsuza kadar devam etmesine neden olur.
- Sonlandırılmamış döngü oluşturmaya eşdeğerdir.
Bu senaryolarda başarısız Blazor olur ve genellikle şunları yapmaya çalışır:
- İşletim sisteminin izin verdiği kadar CPU süresini süresiz olarak tüketin.
- Sınırsız miktarda bellek kullanın. Sınırsız bellek kullanmak, sonlandırılmamış bir döngünün her yinelemedeki bir koleksiyona girişler eklediği senaryoya eşdeğerdir.
Sonsuz özyineleme desenlerini önlemek için özyinelemeli işleme kodunun uygun durdurma koşulları içerdiğinden emin olun.
Özel işleme ağacı mantığı
Çoğu Razor bileşen bileşen dosyası (.razor
) olarak Razor uygulanır ve kendi çıkışını işlemek için üzerinde RenderTreeBuilder çalışan mantık üretmek için çerçeve tarafından derlenir. Ancak, bir geliştirici yordam C# kodunu kullanarak mantığını el ile uygulayabilir RenderTreeBuilder . Daha fazla bilgi için bkz . ASP.NET Çekirdek Blazor gelişmiş senaryoları (işleme ağacı oluşturma).
Uyarı
El ile işleme ağacı oluşturucu mantığının kullanılması gelişmiş ve güvenli olmayan bir senaryo olarak kabul edilir, genel bileşen geliştirme için önerilmez.
Kod yazılırsa RenderTreeBuilder geliştiricinin kodun doğruluğunu garanti etmesi gerekir. Örneğin, geliştirici şunları sağlamalıdır:
- ve CloseElement çağrıları OpenElement doğru şekilde dengelenir.
- Öznitelikler yalnızca doğru yerlere eklenir.
Yanlış el ile işleme ağacı oluşturucu mantığı kilitlenmeler, uygulama veya sunucunun yanıt vermeyi durdurması ve güvenlik açıkları gibi rastgele tanımsız davranışlara neden olabilir.
El ile işleme ağacı oluşturucusu mantığını aynı karmaşıklık düzeyinde ve derleme kodu veya Microsoft Ara Dil (MSIL) yönergelerini el ile yazmayla aynı tehlike düzeyinde kullanmayı göz önünde bulundurun.
Ek kaynaklar
- ASP.NET Core Blazor günlüğü
- ASP.NET Core'daki hataları işleme†
- ASP.NET Core ile web API'leri oluşturma
- Blazorörnekler GitHub deposu () (
dotnet/blazor-samples
nasıl indirilir)
†Uygulama tarafı Blazor uygulamalarının günlüğe kaydetme için kullandığı arka uç ASP.NET Core web API'sine uygulama.
ASP.NET Core