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 8 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
kapsamı tarayıcının penceresine göre belirlenmiştir. 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.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 sessionStorage
ile localStorage
ç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 sessionStorage
için localStorage
ASP.NET Core Data Protection'ı destekler.
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 vesessionStorage
hizmetleri eklemeklocalStorage
için çağrısıAddProtectedBrowserStorage
: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 şablonunu temel alanBlazor bir uygulamanın bileşenindeki Counter
değeri kalıcı hale currentCount
getirmek için yöntemini kullanacak ProtectedSessionStore.SetAsync
şekilde değiştirinIncrementCount
:
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 Counter
geri dönerse , kullanıcının yeni bir bağlantı hattında olup olmadığını da içeren verileri kurtarmak currentCount
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. Türüneint
() bir soru işareti (?
) ekleyerek null atanabilir hale getirincurrentCount
:
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ığı false
işleme modunu prerender
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, Routes
bileşenin Blazor Web App 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 özniteliğini olarak Serverdeğiştirinrender-mode
:
<component type="typeof(App)" render-mode="Server" />
Ön kayıt devre dışı bırakıldığında, içeriğin önceden girilmesi <head>
devre dışı bırakılır.
Ön kayıt, veya sessionStorage
kullanmayan localStorage
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);
}
}
Devlet korumasını ortak bir konuma ayırma
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 bileşen örneğinde CounterStateProvider
, sayaç verileri için sessionStorage
kalıcıdır:
@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 OnInitializedAsync()
{
var result = await ProtectedSessionStore.GetAsync<int>("count");
CurrentCount = result.Success ? result.Value : 0;
isLoaded = true;
}
public async Task SaveChangesAsync()
{
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 OnInitializedAsync()
{
CurrentCount = await ProtectedSessionStore.GetAsync<int>("count");
isLoaded = true;
}
public async Task SaveChangesAsync()
{
await ProtectedSessionStore.SetAsync("count", CurrentCount);
}
}
Not
hakkında RenderFragmentdaha fazla bilgi için bkz . ASP.NET Core Razor bileşenleri.
Bileşen, CounterStateProvider
durum yüklemesi tamamlanana kadar alt içeriğini işlemeyerek yükleme aşamasını işler.
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 (<Router>...</Router>
) Routes
çevresinde Router sarmalarCounterStateProvider
.
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, @true
olarak ayarlanan PreferExactMatches
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)
{
CounterStateProvider.CurrentCount++;
await CounterStateProvider.SaveChangesAsync();
}
}
}
Önceki bileşenin ile ProtectedBrowserStorage
etkileşim kurması gerekmez ve bir "yükleme" aşamasıyla ilgilenmez.
Önceden açıklandığı gibi ön kayıtla başa çıkmak için, CounterStateProvider
sayaç verilerini kullanan tüm bileşenlerin otomatik olarak ön kayıtla çalışması için değiştirilebilir. Daha fazla bilgi için Bkz . Hazırlamayı işleme bölümü.
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/OpenID Connect (OIDC) 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
- BlazorGü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
kapsamı tarayıcının penceresine göre belirlenmiştir. 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.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 sessionStorage
içinde localStorage
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 açıklandığı gibi zincirlenmiş bağlama kullanarak verileri bağlar.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
Özel durum yönetimi hizmetinde, 'nin eşitleme bağlamı Blazordışında çağrılan bir geri çağırmanın işleyicinin eşitleme bağlamı üzerine taşımak için geri çağırmanın mantığını içinde ComponentBase.InvokeAsync sarmalamaları gerekir.
Durum yönetimi hizmeti 'nin eşitleme bağlamında çağrılmazsa StateHasChanged Blazoraş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