ASP.NET Çekirdek Blazor durum yönetimi
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 9 sürümüne bakın.
Bu makalede, bir uygulamayı kullanırken ve tarayıcı oturumlarında kullanıcının verilerini (durumunu) korumaya yönelik yaygın yaklaşımlar açıklanmaktadır.
Not
Bu makaledeki kod örnekleri, .NET 6 veya sonraki sürümlerindeki ASP.NET Core'da desteklenen null atanabilir başvuru türlerini (NTS) ve .NET derleyici null durum statik analizini benimser. ASP.NET Core 5.0 veya önceki sürümleri hedeflerken, makalenin örneklerindeki türlerden null tür atamasını (?
) kaldırın.
Kullanıcı durumunu koruma
Sunucu tarafı Blazor durum bilgisi olan bir uygulama çerçevesidir. Çoğu zaman uygulama sunucuya bir bağlantı tutar. Kullanıcının durumu bir bağlantı hattında sunucunun belleğinde tutulur.
Bir bağlantı hattında tutulan kullanıcı durumu örnekleri şunlardır:
- Bileşen örneklerinin hiyerarşisi ve işlenen kullanıcı arabirimindeki en son işleme çıktısı.
- Bileşen örneklerindeki alanların ve özelliklerin değerleri.
- Bağlantı hattı kapsamındaki bağımlılık ekleme (DI) hizmet örneklerinde tutulan veriler.
Kullanıcı durumu, JavaScript birlikte çalışma çağrıları aracılığıyla tarayıcının bellek kümesindeki JavaScript değişkenlerinde de bulunabilir.
Bir kullanıcı geçici bir ağ bağlantısı kaybıyla karşılaşırsa, Blazor kullanıcıyı özgün durumuyla özgün bağlantı hattına yeniden bağlamayı dener. Ancak, bir kullanıcıyı sunucunun belleğindeki özgün bağlantı hattına yeniden bağlamak her zaman mümkün değildir:
- Sunucu bağlantısı kesilmiş bir devreyi sonsuza kadar tutamaz. Sunucunun zaman aşımından sonra veya sunucu bellek baskısı altındayken bağlantısı kesilmiş bir bağlantı hattını serbest bırakması gerekir.
- Çok sunuculu, yük dengeli dağıtım ortamlarında tek tek sunucular başarısız olabilir veya isteklerin genel hacmini işlemek için artık gerekli olmadığında otomatik olarak kaldırılabilir. Kullanıcının özgün sunucu işleme istekleri, kullanıcı yeniden bağlanmayı denediğinde kullanılamaz duruma gelebilir.
- Kullanıcı tarayıcısını kapatıp yeniden açabileceği gibi, tarayıcının belleğinde tutulan tüm durumları kaldıran sayfayı yeniden yükleyebilir. Örneğin, JavaScript birlikte çalışma çağrıları aracılığıyla ayarlanan JavaScript değişken değerleri kaybolur.
Bir kullanıcı özgün bağlantı hattına yeniden bağlanamayınca, kullanıcı boş durumda yeni bir bağlantı hattı alır. Bu, masaüstü uygulamasını kapatıp yeniden açmakla eşdeğerdir.
Devreler arasında kalıcı durum
Genel olarak, kullanıcıların zaten var olan verileri okumak yerine etkin bir şekilde veri oluşturduğu devreler arasında durumu koruyun.
Devreler arasında durumu korumak için uygulamanın verileri sunucunun belleğinden başka bir depolama konumuna kalıcı hale getirebilmesi gerekir. Durum kalıcılığı otomatik değildir. Durum bilgisi olan veri kalıcılığını uygulamak için uygulamayı geliştirirken adım atmalısınız.
Veri kalıcılığı genellikle yalnızca kullanıcıların oluşturmak için çaba harcamış olduğu yüksek değerli durum için gereklidir. Aşağıdaki örneklerde kalıcı durum, ticari etkinliklerde zaman veya yardım tasarrufu sağlar:
- Çok adımlı web formları: Bir kullanıcının durumu kaybolursa, çok adımlı bir web formunun tamamlanmış birkaç adımı için verileri yeniden girmesi zaman alır. Bir kullanıcı formdan uzaklaşıp daha sonra geri dönerse bu senaryoda durumu kaybeder.
- Alışveriş sepetleri: Bir uygulamanın potansiyel geliri temsil eden ticari açıdan önemli bileşenleri korunabilir. Durumunu ve dolayısıyla alışveriş sepetini kaybeden bir kullanıcı, daha sonra siteye geri döndüğünde daha az ürün veya hizmet satın alabilir.
Bir uygulama yalnızca uygulama durumunu kalıcı hale gelebilir. Bileşen örnekleri ve bunların işleme ağaçları gibi URI'ler kalıcı hale getirilemiyor. Bileşenler ve işleme ağaçları genellikle seri hale getirilemez. Ağaç görünümü denetiminin genişletilmiş düğümleri gibi ui durumunu kalıcı hale getirmek için uygulamanın kullanıcı arabirimi durumunun davranışını serileştirilebilir uygulama durumu olarak modellemek için özel kod kullanması gerekir.
Durumu kalıcı hale getirmek için
Kalıcı durum için ortak konumlar vardır:
Sunucu tarafı depolama
Uygulama, birden çok kullanıcıya ve cihaza yayılan kalıcı veri kalıcılığı için sunucu tarafı depolamayı kullanabilir. Seçenekler arasında bulunanlar:
- Blob depolama
- Anahtar-değer depolama
- İlişkisel veritabanı
- Tablo depolama
Veriler kaydedildikten sonra, kullanıcının durumu korunur ve herhangi bir yeni bağlantı hattında kullanılabilir.
Azure veri depolama seçenekleri hakkında daha fazla bilgi için aşağıdakilere bakın:
URL
Gezinti durumunu temsil eden geçici veriler için verileri URL'nin bir parçası olarak modellenin. URL'de modellenen kullanıcı durumu örnekleri şunlardır:
- Görüntülenen varlığın kimliği.
- Sayfalanmış kılavuzdaki geçerli sayfa numarası.
Tarayıcının adres çubuğunun içeriği korunur:
- Kullanıcı sayfayı el ile yeniden yüklerse.
- Web sunucusu kullanılamaz duruma gelirse ve kullanıcı farklı bir sunucuya bağlanmak için sayfayı yeniden yüklemeye zorlanırsa.
yönergesiyle @page
URL desenlerini tanımlama hakkında bilgi için bkz . ASP.NET Çekirdek Blazor yönlendirme ve gezinti.
Tarayıcı depolama alanı
Kullanıcının etkin olarak oluşturduğu geçici veriler için yaygın olarak kullanılan depolama konumu tarayıcının localStorage
ve sessionStorage
koleksiyonlarıdır:
-
localStorage
, tarayıcının belirli örneğiyle sınırlıdır. Kullanıcı sayfayı yeniden yüklerse veya tarayıcıyı kapatıp yeniden açarsa durum devam eder. Kullanıcı birden çok tarayıcı sekmesi açarsa, durum sekmeler arasında paylaşılır. Veriler açıkça temizlenene kadar içindelocalStorage
kalır. "Özel gözatma" veya "gizli" oturumda yüklenen bir belgeninlocalStorage
verileri, son "özel" sekme kapatıldığında temizlenir. -
sessionStorage
kapsamı tarayıcı sekmesine göre belirlenmiştir. Kullanıcı sekmeyi yeniden yüklerse durum devam eder. Kullanıcı sekmeyi veya tarayıcıyı kapatırsa durum kaybolur. Kullanıcı birden çok tarayıcı sekmesi açarsa, her sekmenin kendi bağımsız veri sürümü vardır.
sessionStorage
Genellikle kullanımı daha güvenlidir.
sessionStorage
kullanıcının birden çok sekme açması ve aşağıdakilerle karşılaşması riskini önler:
- Sekmeler arasında durum depolamadaki hatalar.
- Bir sekme diğer sekmelerin durumunun üzerine yazıldığında kafa karıştırıcı davranış.
localStorage
, uygulamanın tarayıcıyı kapatma ve yeniden açma işlemi boyunca durumu kalıcı hale döndürmesi gerekiyorsa daha iyi bir seçenektir.
Tarayıcı depolamayı kullanmayla ilgili uyarılar:
- Sunucu tarafı veritabanı kullanımına benzer şekilde, verileri yükleme ve kaydetme zaman uyumsuz bir işlemdir.
- İstenen sayfa, ön kayıt sırasında tarayıcıda mevcut olmadığından, yerel depolama önceden kullanım sırasında kullanılamaz.
- Sunucu tarafı Blazor uygulamalar için birkaç kilobaytlık veri depolamanın kalıcı olması mantıklıdır. Veriler ağ üzerinden yüklenip kaydedildiğinden, birkaç kilobayttan fazla performans etkilerini göz önünde bulundurmanız gerekir.
- Kullanıcılar verileri görüntüleyebilir veya üzerinde değişiklik yapabilir. ASP.NET Core Data Protection riski azaltabilir. Örneğin, ASP.NET Core Protected Browser Storage ASP.NET Core Data Protection kullanır.
Üçüncü taraf NuGet paketleri ve localStorage
ile sessionStorage
çalışmak için API'ler sağlar. ASP.NET Core Data Protection'ASP.NET saydam olarak kullanan bir paket seçmeyi göz önünde bulundurmaya değer. Veri Koruması depolanan verileri şifreler ve depolanan verilerle oynanma riskini azaltır. JSON serileştirilmiş verileri düz metin olarak depolanıyorsa, kullanıcılar tarayıcı geliştirici araçlarını kullanarak verileri görebilir ve depolanan verileri değiştirebilir. Önemsiz verilerin güvenliğini sağlamak bir sorun değildir. Örneğin, kullanıcı arabirimi öğesinin depolanan rengini okumak veya değiştirmek kullanıcı veya kuruluş için önemli bir güvenlik riski değildir. Kullanıcıların hassas verileri incelemesine veya kurcalamasına izin vermekten kaçının.
ASP.NET Core Korumalı Tarayıcı Depolama alanı
ASP.NET Core Protected Browser Storage, ve için localStorage
ASP.NET Core Data Protection'ısessionStorage
.
Not
Protected Browser Storage, ASP.NET Core Data Protection'a dayanır ve yalnızca sunucu tarafı Blazor uygulamalar için desteklenir.
Uyarı
Microsoft.AspNetCore.ProtectedBrowserStorage
, üretim kullanımına yönelik olmayan desteklenmeyen, deneysel bir pakettir.
Paket yalnızca ASP.NET Core 3.1 uygulamalarında kullanılabilir.
Yapılandırma
öğesine
Microsoft.AspNetCore.ProtectedBrowserStorage
bir paket başvurusu ekleyin.Not
.NET uygulamalarına paket ekleme hakkında yönergeler için, Paket tüketimi iş akışında (NuGet belgeleri)paketleri yüklemek ve yönetmek altındaki makalelere bakın. NuGet.org'da doğru paket sürümlerini onaylayın.
Dosyada
_Host.cshtml
, kapanış</body>
etiketinin içine aşağıdaki betiği ekleyin:<script src="_content/Microsoft.AspNetCore.ProtectedBrowserStorage/protectedBrowserStorage.js"></script>
içinde
Startup.ConfigureServices
, hizmet koleksiyonuna veAddProtectedBrowserStorage
hizmetleri eklemeklocalStorage
için çağrısısessionStorage
:services.AddProtectedBrowserStorage();
Bir bileşen içindeki verileri kaydetme ve yükleme
Tarayıcı depolama alanına veri yüklemeyi veya kaydetmeyi gerektiren herhangi bir bileşende @inject
, aşağıdakilerden birinin örneğini eklemek için yönergesini kullanın:
ProtectedLocalStorage
ProtectedSessionStorage
Seçim, kullanmak istediğiniz tarayıcı depolama konumuna bağlıdır. Aşağıdaki örnekte, sessionStorage
kullanılır:
@using Microsoft.AspNetCore.Components.Server.ProtectedBrowserStorage
@inject ProtectedSessionStorage ProtectedSessionStore
@using Microsoft.AspNetCore.ProtectedBrowserStorage
@inject ProtectedSessionStorage ProtectedSessionStore
yönergesi @using
, bileşeni yerine uygulamanın _Imports.razor
dosyasına yerleştirilebilir.
_Imports.razor
Dosyanın kullanılması, ad alanını uygulamanın daha büyük kesimleri veya uygulamanın tamamı için kullanılabilir hale getirir.
Proje şablonunuCounter
bir uygulamanın bileşenindeki Blazor değeri kalıcı hale getirmek için yöntemini kullanacak IncrementCount
şekilde değiştirinProtectedSessionStore.SetAsync
:
private async Task IncrementCount()
{
currentCount++;
await ProtectedSessionStore.SetAsync("count", currentCount);
}
Daha büyük ve daha gerçekçi uygulamalarda, tek tek alanların depolanması olası olmayan bir senaryodur. Uygulamaların karmaşık durum içeren tüm model nesnelerini depolama olasılığı daha yüksektir.
ProtectedSessionStore
karmaşık durum nesnelerini depolamak için JSON verilerini otomatik olarak serileştirir ve seri durumdan çıkartır.
Yukarıdaki kod örneğinde currentCount
veriler kullanıcının tarayıcısında olduğu gibi sessionStorage['count']
depolanır. Veriler düz metin olarak depolanmaz, bunun yerine ASP.NET Core Data Protection kullanılarak korunur. Şifrelenmiş veriler tarayıcının geliştirici konsolunda değerlendirilirse sessionStorage['count']
incelenebilir.
Kullanıcı daha sonra bileşene currentCount
geri dönerse , kullanıcının yeni bir bağlantı hattında olup olmadığını da içeren verileri kurtarmak Counter
için kullanınProtectedSessionStore.GetAsync
:
protected override async Task OnInitializedAsync()
{
var result = await ProtectedSessionStore.GetAsync<int>("count");
currentCount = result.Success ? result.Value : 0;
}
protected override async Task OnInitializedAsync()
{
currentCount = await ProtectedSessionStore.GetAsync<int>("count");
}
Bileşenin parametreleri gezinti durumu içeriyorsa, çağrısı ProtectedSessionStore.GetAsync
yapıp yerine içinde sonuç olmayannull
bir sonuç atayınOnParametersSetAsyncOnInitializedAsync.
OnInitializedAsync yalnızca bileşen ilk kez başlatıldığında çağrılır.
OnInitializedAsync daha sonra kullanıcı aynı sayfada kalırken farklı bir URL'ye giderse yeniden çağrılmaz. Daha fazla bilgi için bkz. ASP.NET Core Razor bileşeni yaşam döngüsü.
Uyarı
Bu bölümdeki örnekler yalnızca sunucuda ön kayıt etkinleştirilmemişse çalışır. Ön kayıt etkinleştirildiğinde, bileşen önceden girildiğinden JavaScript birlikte çalışma çağrılarının verilemediğini açıklayan bir hata oluşturulur.
Prerendering'i devre dışı bırakın veya ön kayıtla çalışmak için ek kod ekleyin. Prerendering ile çalışan kod yazma hakkında daha fazla bilgi edinmek için Bkz . Hazırlamayı işleme bölümü.
Yükleme durumunu işleme
Tarayıcı depolamaya bir ağ bağlantısı üzerinden zaman uyumsuz olarak erişildiğinden, veriler yüklenmeden ve bir bileşen tarafından kullanılabilir duruma gelmeden önce her zaman bir süre vardır. En iyi sonuçlar için, boş veya varsayılan veriler görüntülemek yerine yükleme işlemi devam ederken bir ileti işleyin.
Bir yaklaşım, verilerin olup olmadığını izlemektir null
. Bu da verilerin yüklenmeye devam ettiği anlamına gelir. Varsayılan Counter
bileşende, sayı bir int
içinde tutulur.
?
hale getirinint
:
private int? currentCount;
Sayıyı ve Increment
düğmeyi koşulsuz olarak görüntülemek yerine, yalnızca veriler denetlenerek HasValueyüklenirse bu öğeleri görüntüleyin:
@if (currentCount.HasValue)
{
<p>Current count: <strong>@currentCount</strong></p>
<button @onclick="IncrementCount">Increment</button>
}
else
{
<p>Loading...</p>
}
İşle prerendering
Prerendering sırasında:
- Kullanıcının tarayıcısıyla etkileşimli bir bağlantı yoktur.
- Tarayıcının henüz JavaScript kodu çalıştırabileceği bir sayfası yok.
localStorage
veya sessionStorage
prerendering sırasında kullanılamaz. Bileşen depolamayla etkileşim kurmaya çalışırsa, bileşen önceden oluşturulduğundan JavaScript birlikte çalışma çağrılarının verilemediğini açıklayan bir hata oluşturulur.
Hatayı düzeltmenin bir yolu, ön kayıt işlemini devre dışı bırakmaktır. Uygulama tarayıcı tabanlı depolamayı yoğun bir şekilde kullanıyorsa bu genellikle en iyi seçenektir. Prerendering karmaşıklık ekler ve uygulama kullanıma sunulana kadar localStorage
sessionStorage
yararlı içerik önyazılamadığından uygulamaya fayda sağlamaz.
Ön kayıt özelliğini devre dışı bırakmak için, uygulamanın bileşen hiyerarşisinde kök bileşen olmayan en üst düzey bileşende parametresinin ayarlandığı prerender
işleme modunu false
belirtin.
Not
Kök bileşeni etkileşimli hale getirme (bileşen gibi App
) desteklenmez. Bu nedenle, prerendering bileşeni tarafından App
doğrudan devre dışı bırakılamaz.
Proje şablonunu temel alan uygulamalar için, Blazor Web App bileşenin Routes
bileşende App
Components/App.razor
():
<Routes @rendermode="new InteractiveServerRenderMode(prerender: false)" />
Ayrıca, bileşen için HeadOutlet
ön kayıt özelliğini devre dışı bırakın:
<HeadOutlet @rendermode="new InteractiveServerRenderMode(prerender: false)" />
Daha fazla bilgi için bkz . ASP.NET Core Blazor işleme modları.
Ön kayıt özelliğini devre dışı bırakmak için dosyayı açın _Host.cshtml
ve Bileşen Etiketi Yardımcısı'nın render-mode
özniteliğini olarak değiştirinServer:
<component type="typeof(App)" render-mode="Server" />
Ön kayıt, veya localStorage
kullanmayan sessionStorage
diğer sayfalar için yararlı olabilir. Ön çalıştırmayı korumak için, tarayıcı bağlantı hattına bağlanana kadar yükleme işlemini erteleyin. Aşağıda, sayaç değerini depolamak için bir örnek verilmiştir:
@using Microsoft.AspNetCore.Components.Server.ProtectedBrowserStorage
@inject ProtectedLocalStorage ProtectedLocalStore
@if (isConnected)
{
<p>Current count: <strong>@currentCount</strong></p>
<button @onclick="IncrementCount">Increment</button>
}
else
{
<p>Loading...</p>
}
@code {
private int currentCount;
private bool isConnected;
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender)
{
isConnected = true;
await LoadStateAsync();
StateHasChanged();
}
}
private async Task LoadStateAsync()
{
var result = await ProtectedLocalStore.GetAsync<int>("count");
currentCount = result.Success ? result.Value : 0;
}
private async Task IncrementCount()
{
currentCount++;
await ProtectedLocalStore.SetAsync("count", currentCount);
}
}
@using Microsoft.AspNetCore.ProtectedBrowserStorage
@inject ProtectedLocalStorage ProtectedLocalStore
@if (isConnected)
{
<p>Current count: <strong>@currentCount</strong></p>
<button @onclick="IncrementCount">Increment</button>
}
else
{
<p>Loading...</p>
}
@code {
private int currentCount = 0;
private bool isConnected = false;
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender)
{
isConnected = true;
await LoadStateAsync();
StateHasChanged();
}
}
private async Task LoadStateAsync()
{
currentCount = await ProtectedLocalStore.GetAsync<int>("count");
}
private async Task IncrementCount()
{
currentCount++;
await ProtectedLocalStore.SetAsync("count", currentCount);
}
}
Durum korumayı ortak bir sağlayıcıya ayır
Birçok bileşen tarayıcı tabanlı depolamayı kullanırsa, durum sağlayıcısı kodunun birçok kez uygulanması kod yinelemesi oluşturur. Kod yinelemesini önlemenin bir seçeneği, durum sağlayıcısı mantığını kapsülleyen bir durum sağlayıcısı üst bileşeni oluşturmaktır. Alt bileşenler, durum kalıcılığı mekanizmasına bakılmaksızın kalıcı verilerle çalışabilir.
Aşağıdaki CounterStateProvider
bileşeni örneğinde, sayaç verileri sessionStorage
olarak kalıcı hale getirilir ve durum yüklemesi tamamlanana kadar alt içeriğini işlemeyerek yükleme aşamasını işler.
Bu bölümdeki yaklaşım, abone olunan birden çok bileşenin aynı sayfada yeniden yenilenmesi tetikleme özelliğine sahip değildir. Abone olunan bileşenlerden biri durumu değiştirirse, yeniden açılır ve güncelleştirilmiş durumu görüntüleyebilir, ancak aynı sayfada bu durumu görüntüleyen farklı bir bileşen, kendi sonraki rerender'ine kadar eski verileri görüntüler. Bu nedenle, bu bölümde açıklanan yaklaşım, sayfadaki tek bir bileşende durum kullanmak için en uygun yöntemdir.
CounterStateProvider.razor
:
@using Microsoft.AspNetCore.Components.Server.ProtectedBrowserStorage
@inject ProtectedSessionStorage ProtectedSessionStore
@if (isLoaded)
{
<CascadingValue Value="this">
@ChildContent
</CascadingValue>
}
else
{
<p>Loading...</p>
}
@code {
private bool isLoaded;
[Parameter]
public RenderFragment? ChildContent { get; set; }
public int CurrentCount { get; set; }
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender)
{
isLoaded = true;
await LoadStateAsync();
StateHasChanged();
}
}
private async Task LoadStateAsync()
{
var result = await ProtectedSessionStore.GetAsync<int>("count");
CurrentCount = result.Success ? result.Value : 0;
isLoaded = true;
}
public async Task IncrementCount()
{
CurrentCount++;
await ProtectedSessionStore.SetAsync("count", CurrentCount);
}
}
@using Microsoft.AspNetCore.ProtectedBrowserStorage
@inject ProtectedSessionStorage ProtectedSessionStore
@if (isLoaded)
{
<CascadingValue Value="this">
@ChildContent
</CascadingValue>
}
else
{
<p>Loading...</p>
}
@code {
private bool isLoaded;
[Parameter]
public RenderFragment ChildContent { get; set; }
public int CurrentCount { get; set; }
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender)
{
isLoaded = true;
await LoadStateAsync();
StateHasChanged();
}
}
private async Task LoadStateAsync()
{
CurrentCount = await ProtectedSessionStore.GetAsync<int>("count");
isLoaded = true;
}
public async Task IncrementCount()
{
CurrentCount++;
await ProtectedSessionStore.SetAsync("count", CurrentCount);
}
}
Not
hakkında RenderFragmentdaha fazla bilgi için bkz . ASP.NET Core Razor bileşenleri.
Durumu bir uygulamadaki tüm bileşenler için erişilebilir hale getirmek için, genel etkileşimli sunucu tarafı işleme (etkileşimli SSR) ile bileşenin içindeki (CounterStateProvider
) Router çevresinde <Router>...</Router>
sarmalarRoutes
.
App
bileşeninde (Components/App.razor
):
<Routes @rendermode="InteractiveServer" />
Routes
bileşeninde (Components/Routes.razor
):
Bileşeni kullanmak CounterStateProvider
için, karşı duruma erişim gerektiren diğer bileşenlerin etrafında bileşenin bir örneğini sarmalar. Durumu bir uygulamadaki tüm bileşenler için erişilebilir hale getirmek için bileşeni CounterStateProvider
Router bileşenin App
içinde (App.razor
):
<CounterStateProvider>
<Router ...>
...
</Router>
</CounterStateProvider>
Not
ASP.NET Core 5.0.1 sürümünün yayınlanmasıyla ve diğer 5. x sürümleri için Router
bileşeni, PreferExactMatches
olarak ayarlanan @true
parametresini içerir. Daha fazla bilgi için, bkz. ASP.NET Core 3.1'den 5.0'a geçiş.
Sarmalanmış bileşenler kalıcı sayaç durumunu alır ve değiştirebilir. Aşağıdaki Counter
bileşen deseni uygular:
@page "/counter"
<p>Current count: <strong>@CounterStateProvider?.CurrentCount</strong></p>
<button @onclick="IncrementCount">Increment</button>
@code {
[CascadingParameter]
private CounterStateProvider? CounterStateProvider { get; set; }
private async Task IncrementCount()
{
if (CounterStateProvider is not null)
{
await CounterStateProvider.IncrementCount();
}
}
}
Önceki bileşenin ile ProtectedBrowserStorage
etkileşim kurması gerekmez ve bir "yükleme" aşamasıyla ilgilenmez.
Genel olarak, durum sağlayıcısı üst bileşen deseni önerilir:
- Birçok bileşende durumu tüketmek için.
- Kalıcı olarak yalnızca bir üst düzey durum nesnesi varsa.
Birçok farklı durum nesnesini kalıcı hale getirmek ve farklı yerlerdeki nesnelerin farklı alt kümelerini kullanmak için, durumu genel olarak kalıcı hale getirmekten kaçınmak daha iyidir.
Bir Blazor WebAssembly uygulamada oluşturulan kullanıcı durumu tarayıcının belleğinde tutulur.
Tarayıcı belleğinde tutulan kullanıcı durumu örnekleri şunlardır:
- Bileşen örneklerinin hiyerarşisi ve işlenen kullanıcı arabirimindeki en son işleme çıktısı.
- Bileşen örneklerindeki alanların ve özelliklerin değerleri.
- Bağımlılık ekleme (DI) hizmet örneklerinde tutulan veriler.
- JavaScript birlikte çalışma çağrıları aracılığıyla ayarlanan değerler.
Kullanıcı tarayıcısını kapatıp yeniden açtığınızda veya sayfayı yeniden yüklediğinde, tarayıcının belleğinde tutulan kullanıcı durumu kaybolur.
Not
Protected Browser Storage (Microsoft.AspNetCore.Components.Server.ProtectedBrowserStorage ad alanı), ASP.NET Çekirdek Veri Koruması'nı temel alır ve yalnızca sunucu tarafı Blazor uygulamalar için desteklenir.
Tarayıcı oturumları arasında kalıcı durum
Genel olarak, kullanıcıların zaten var olan verileri okumak yerine etkin bir şekilde veri oluşturduğu tarayıcı oturumlarında durumu koruyun.
Tarayıcı oturumlarında durumu korumak için uygulamanın verileri tarayıcının belleğinden başka bir depolama konumuna kalıcı hale getirmek gerekir. Durum kalıcılığı otomatik değildir. Durum bilgisi olan veri kalıcılığını uygulamak için uygulamayı geliştirirken adım atmalısınız.
Veri kalıcılığı genellikle yalnızca kullanıcıların oluşturmak için çaba harcamış olduğu yüksek değerli durum için gereklidir. Aşağıdaki örneklerde kalıcı durum, ticari etkinliklerde zaman veya yardım tasarrufu sağlar:
- Çok adımlı web formları: Bir kullanıcının durumu kaybolursa, çok adımlı bir web formunun tamamlanmış birkaç adımı için verileri yeniden girmesi zaman alır. Bir kullanıcı formdan uzaklaşıp daha sonra geri dönerse bu senaryoda durumu kaybeder.
- Alışveriş sepetleri: Bir uygulamanın potansiyel geliri temsil eden ticari açıdan önemli bileşenleri korunabilir. Durumunu ve dolayısıyla alışveriş sepetini kaybeden bir kullanıcı, daha sonra siteye geri döndüğünde daha az ürün veya hizmet satın alabilir.
Bir uygulama yalnızca uygulama durumunu kalıcı hale gelebilir. Bileşen örnekleri ve bunların işleme ağaçları gibi URI'ler kalıcı hale getirilemiyor. Bileşenler ve işleme ağaçları genellikle seri hale getirilemez. Ağaç görünümü denetiminin genişletilmiş düğümleri gibi ui durumunu kalıcı hale getirmek için uygulamanın kullanıcı arabirimi durumunun davranışını serileştirilebilir uygulama durumu olarak modellemek için özel kod kullanması gerekir.
Durumu kalıcı hale getirmek için
Kalıcı durum için ortak konumlar vardır:
Sunucu tarafı depolama
Birden çok kullanıcıya ve cihaza yayılan kalıcı veri kalıcılığı için uygulama, bir web API'si aracılığıyla erişilen bağımsız sunucu tarafı depolamayı kullanabilir. Seçenekler arasında bulunanlar:
- Blob depolama
- Anahtar-değer depolama
- İlişkisel veritabanı
- Tablo depolama
Veriler kaydedildikten sonra, kullanıcının durumu korunur ve herhangi bir yeni tarayıcı oturumunda kullanılabilir.
Blazor WebAssembly Uygulamalar tamamen kullanıcının tarayıcısında çalıştığından, depolama hizmetleri ve veritabanları gibi güvenli dış sistemlere erişmek için ek ölçüler gerektirir. Blazor WebAssembly uygulamaları tek sayfalı uygulamalarla (SPA'lar) aynı şekilde güvenli hale getirilir. Genellikle, bir uygulama OAuth/ aracılığıyla kullanıcının kimliğini doğrular ve ardından sunucu tarafı bir uygulamaya web API çağrıları aracılığıyla depolama hizmetleri ve veritabanlarıyla etkileşim kurar. Sunucu tarafı uygulaması, uygulama ile depolama hizmeti veya veritabanı arasında Blazor WebAssembly veri aktarımına aracılık eder. Uygulama Blazor WebAssembly , sunucu tarafı uygulamasına kısa ömürlü bir bağlantı tutarken, sunucu tarafı uygulamasının depolamaya kalıcı bir bağlantısı vardır.
Daha fazla bilgi edinmek için aşağıdaki kaynaklara bakın:
- ASP.NET Core Blazor uygulamasından web API'sini çağırma
- Güvenli ASP.NET Çekirdeği Blazor WebAssembly
- Blazor Güvenlik ve Identity makaleler
Azure veri depolama seçenekleri hakkında daha fazla bilgi için aşağıdakilere bakın:
URL
Gezinti durumunu temsil eden geçici veriler için verileri URL'nin bir parçası olarak modellenin. URL'de modellenen kullanıcı durumu örnekleri şunlardır:
- Görüntülenen varlığın kimliği.
- Sayfalanmış kılavuzdaki geçerli sayfa numarası.
Kullanıcı sayfayı el ile yeniden yüklerse tarayıcının adres çubuğunun içeriği korunur.
yönergesiyle @page
URL desenlerini tanımlama hakkında bilgi için bkz . ASP.NET Çekirdek Blazor yönlendirme ve gezinti.
Tarayıcı depolama alanı
Kullanıcının etkin olarak oluşturduğu geçici veriler için yaygın olarak kullanılan depolama konumu tarayıcının localStorage
ve sessionStorage
koleksiyonlarıdır:
-
localStorage
, tarayıcı örneğine özgü olarak kapsamlandırılmıştır. Kullanıcı sayfayı yeniden yüklerse veya tarayıcıyı kapatıp yeniden açarsa durum devam eder. Kullanıcı birden çok tarayıcı sekmesi açarsa, durum sekmeler arasında paylaşılır. Veriler açıkça temizlenene kadar içindelocalStorage
kalır. "Özel gözatma" veya "gizli" oturumda yüklenen bir belgeninlocalStorage
verileri, son "özel" sekme kapatıldığında temizlenir. -
sessionStorage
kapsamı tarayıcı sekmesine göre belirlenmiştir. Kullanıcı sekmeyi yeniden yüklerse durum devam eder. Kullanıcı sekmeyi veya tarayıcıyı kapatırsa durum kaybolur. Kullanıcı birden çok tarayıcı sekmesi açarsa, her sekmenin kendi bağımsız veri sürümü vardır.
Not
localStorage
ve sessionStorage
uygulamalarda yalnızca özel kod yazarak veya bir üçüncü taraf paketi kullanarak kullanılabilir Blazor WebAssembly .
sessionStorage
Genellikle kullanımı daha güvenlidir.
sessionStorage
kullanıcının birden çok sekme açması ve aşağıdakilerle karşılaşması riskini önler:
- Sekmeler arasında durum depolamadaki hatalar.
- Bir sekme diğer sekmelerin durumunun üzerine yazıldığında kafa karıştırıcı davranış.
localStorage
, uygulamanın tarayıcıyı kapatma ve yeniden açma işlemi boyunca durumu kalıcı hale döndürmesi gerekiyorsa daha iyi bir seçenektir.
Uyarı
Kullanıcılar ve localStorage
içinde sessionStorage
depolanan verileri görüntüleyebilir veya üzerinde değişiklik yapabilir.
Bellek içi durum kapsayıcı hizmeti
İç içe bileşenler genellikle ASP.NET Core veri bağlamasında Blazor. İç içe ve kaydedilmemiş bileşenler, kayıtlı bir bellek içi durum kapsayıcısı kullanarak verilere erişimi paylaşabilir. Özel durum kapsayıcı sınıfı, uygulamanın farklı bölümlerindeki bileşenlere durum değişikliklerini bildirmek için atanabilir Action kullanabilir. Aşağıdaki örnekte:
- Bir bileşen çifti, bir özelliği izlemek için durum kapsayıcısı kullanır.
- Aşağıdaki örnekteki bir bileşen diğer bileşende iç içe yerleştirilmiştir, ancak bu yaklaşımın çalışması için iç içe yerleştirme gerekli değildir.
Önemli
Bu bölümdeki örnekte bellek içi durum kapsayıcı hizmetinin nasıl oluşturulacağı, hizmetin nasıl kaydedilacağı ve hizmetin bileşenlerde nasıl kullanılacağı gösterilmektedir. Örnek, daha fazla geliştirme yapılmadan verileri kalıcı hale gelmez. Verilerin kalıcı olarak depolanması için durum kapsayıcısının tarayıcı belleği temizlendiğinde devam eden temel bir depolama mekanizması benimsemesi gerekir. Bu, veya başka bir teknolojiyle localStorage
/sessionStorage
gerçekleştirilebilir.
StateContainer.cs
:
public class StateContainer
{
private string? savedString;
public string Property
{
get => savedString ?? string.Empty;
set
{
savedString = value;
NotifyStateChanged();
}
}
public event Action? OnChange;
private void NotifyStateChanged() => OnChange?.Invoke();
}
İstemci tarafı uygulamaları (Program
dosya):
builder.Services.AddSingleton<StateContainer>();
Sunucu tarafı uygulamalar (Program
.NET 6 veya sonraki sürümlerde dosya, ASP.NET Core):
builder.Services.AddScoped<StateContainer>();
Sunucu tarafı uygulamaları (Startup.ConfigureServices
Startup.cs
6.0'dan önceki ASP.NET Core):
services.AddScoped<StateContainer>();
Shared/Nested.razor
:
@implements IDisposable
@inject StateContainer StateContainer
<h2>Nested component</h2>
<p>Nested component Property: <b>@StateContainer.Property</b></p>
<p>
<button @onclick="ChangePropertyValue">
Change the Property from the Nested component
</button>
</p>
@code {
protected override void OnInitialized()
{
StateContainer.OnChange += StateHasChanged;
}
private void ChangePropertyValue()
{
StateContainer.Property =
$"New value set in the Nested component: {DateTime.Now}";
}
public void Dispose()
{
StateContainer.OnChange -= StateHasChanged;
}
}
StateContainerExample.razor
:
@page "/state-container-example"
@implements IDisposable
@inject StateContainer StateContainer
<h1>State Container Example component</h1>
<p>State Container component Property: <b>@StateContainer.Property</b></p>
<p>
<button @onclick="ChangePropertyValue">
Change the Property from the State Container Example component
</button>
</p>
<Nested />
@code {
protected override void OnInitialized()
{
StateContainer.OnChange += StateHasChanged;
}
private void ChangePropertyValue()
{
StateContainer.Property = "New value set in the State " +
$"Container Example component: {DateTime.Now}";
}
public void Dispose()
{
StateContainer.OnChange -= StateHasChanged;
}
}
Önceki bileşenler uygular IDisposableve OnChange
bileşenler atıldığında çerçeve tarafından çağrılan yöntemlerde Dispose
temsilcilerin aboneliği kaldırılır. Daha fazla bilgi için bkz. ASP.NET Core Razor bileşeni yaşam döngüsü.
Ek yaklaşımlar
Özel durum depolaması uygularken, basamaklı değerleri ve parametreleri benimsemek yararlı bir yaklaşımdır:
- Birçok bileşende durumu tüketmek için.
- Kalıcı olarak yalnızca bir üst düzey durum nesnesi varsa.
Sorun giderme
Blazoreşitleme bağlamı dışından durum değişikliklerini desteklemek istediğiniz bir özel durum yönetimi hizmeti kullanırken (örneğin, zamanlayıcı veya arka plan hizmetinden), tüm tüketen bileşenler StateHasChanged çağrısını ComponentBase.InvokeAsynciçinde sarmalamalıdır. Bu, değişiklik bildiriminin işleyicinin eşitleme bağlamında işlenmesini sağlar.
Durum yönetimi hizmeti 'nin eşitleme bağlamında çağrılmazsa StateHasChangedBlazoraşağıdaki hata oluşur:
System.InvalidOperationException: 'Geçerli iş parçacığı Dispatcher ile ilişkili değil. İşleme veya bileşen durumunu tetiklerken yürütmeyi Dispatcher'a geçmek için InvokeAsync() kullanın.'
Bu hatayı giderme hakkında daha fazla bilgi ve örnek için bkz . ASP.NET Core Razor bileşeni işleme.
Ek kaynaklar
- Kimlik doğrulama işleminden önce uygulama durumunu kaydetme (Blazor WebAssembly)
- Dış sunucu API'sini kullanarak durumu yönetme
ASP.NET Core