ASP.NET Çekirdek Blazor durum yönetimi

Not

Bu, bu makalenin en son sürümü değildir. Geçerli sürüm için bu makalenin .NET 8 sürümüne bakın.

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.

Önemli

Bu bilgiler, ticari olarak piyasaya sürülmeden önce önemli ölçüde değiştirilebilen bir yayın öncesi ürünle ilgilidir. Burada verilen bilgilerle ilgili olarak Microsoft açık veya zımni hiçbir garanti vermez.

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çinde localStorage 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 sessionStorageile 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 sessionStorageiç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

  1. öğesine Microsoft.AspNetCore.ProtectedBrowserStoragebir 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.

  2. Dosyada _Host.cshtml , kapanış </body> etiketinin içine aşağıdaki betiği ekleyin:

    <script src="_content/Microsoft.AspNetCore.ProtectedBrowserStorage/protectedBrowserStorage.js"></script>
    
  3. içindeStartup.ConfigureServices, hizmet koleksiyonuna ve sessionStorage hizmetleri eklemek localStorage 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 intiç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 AppComponents/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 sessionStoragekullanmayan 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 sessionStoragekalı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 ProtectedBrowserStorageetkileş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:

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çinde localStorage 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 sessionStorageiç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.cs6.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