インフラジスティックス・ジャパン株式会社Blog

インフラジスティックス・ジャパン株式会社のチームメンバーが技術トレンド、製品Tips、サポート情報からライセンス、日々の業務から感じることなど、さまざまなトピックについてお伝えするBlogです。

Blazor で Web Storage を利用して一時的にデータを保存する方法

f:id:ykinfragistics:20220119170731p:plain

皆さん、こんにちは!
ソリューションコンサルタントの狩谷です。 この記事では、Blazor で Web Storage を利用する方法について解説したいと思います。

本記事は Qiita のドキュメントのミラーです。

qiita.com

この記事では、Blazor で Web Storage を利用する方法について解説したいと思います。 ユーザーがリロードすると画面上の情報が失われてしまいます。その際に、データを一時的に保存しておき、状態を維持する方法を見ていきたいと思います。

Web Storage とは?

HTML5 で導入されたブラウザーに Key-Value 形式でテキストデータを保存できる仕組みです。ブラウザーにデータを保管する仕組みとしては Cookie がありますが、Cookie よりも保存容量が大きく、常に Http Header で送信されるわけではなく、必要なときにだけ取り出せます。 sessionStroage と localStorage の2種類があり、目的に応じて使い分けができます。

  • sessionStorage

ブラウザーのタブ単位でデータを保存できます。タブを再読込してもデータは維持されますが、タブかブラウザーを閉じると、データは失われます。

  • localStorage

ブラウザー単位でデータを保存でき、タブやブラウザー本体を閉じてもデータが維持されます。再度ブラウザーを起動するとデータを再読み込みできます。

Blazor Server で Web Storage を利用する方法

まずは、Blazor Server で Web Storage を利用する方法をご紹介したいと思います。 Blazor Server では Microsoft が提供している、「ASP.NET Core で保護されたブラウザー ストレージ」を利用することで、簡単にデータを暗号化して保存できます。

sessionStorage の場合

@page "/countersession"
@using Microsoft.AspNetCore.Components.Server.ProtectedBrowserStorage
@inject ProtectedSessionStorage ProtectedSessionStore

<PageTitle>Counter</PageTitle>

<h1>Counter</h1>

@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;

    /// <summary>
    /// コンポーネントのレンダリングが完了した後に呼び出されます
    /// </summary>
    /// <param name="firstRender"></param>
    /// <returns></returns>
    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        if (firstRender)
        {
            isConnected = true;
            await LoadStateAsync();
            StateHasChanged();
        }
    }

    private async Task LoadStateAsync()
    {
        var result = await ProtectedSessionStore.GetAsync<int>("count");
        currentCount = result.Success ? result.Value : 0;
    }

    private async Task IncrementCount()
    {
        currentCount++;
        await ProtectedSessionStore.SetAsync("count", currentCount);
    }
}

Microsoft.AspNetCore.Components.Server.ProtectedBrowserStorage を読み込むことにより、ProtectedSessionStorage を利用できます。 sessionStorage、localStorage は、プリレンダリング中に利用できないため、OnInitializedAsync ではなく、OnAfterRenderAsync に画面読み込み時のデータ読み取り処理を記述します。 これで画面をリロードした際も、同じタブ内であればデータを保存し、再読み込みできます。

また、データが暗号化されていることも、開発者ツールから確認できます。 image.png

localStorage の場合

ProtectedSessionStorage を ProtectedLocalStorage に変更するだけです。 localStorage の場合は、ブラウザーを終了してもデータが保存されます。再度ブラウザーを起動すれば保存した値を読み込むことが可能です。localStorage に保存したデータは、有効期限がないため、システムから削除するか、ユーザーが自分で削除しない限りデータが残り続けることに注意してください。

localStorage の場合も、同様にデータが暗号化されます。

Blazor WebAssembly で Web Stroage を利用する方法

Blazor WebAssembly の場合は、Microsoft.AspNetCore.Components.Server.ProtectedBrowserStorage を利用できないため、サードパーティ製のライブラリを利用した例をご紹介します。

今回は、Blazored というライブラリを使ってみます。(https://github.com/Blazored) 導入は Nuget から、Blazored.SessionStorage、Blazored.LocalStorage を検索すると見つかります。 image.png

sessionStorage の場合

Blazored.SessionStorage を読み込み、builder にサービスを登録します。これで各 Razor コンポーネントから利用できます。

using Blazored.SessionStorage;

...

builder.Services.AddBlazoredSessionStorage();

await builder.Build().RunAsync();
@page "/counter"
@inject Blazored.SessionStorage.ISessionStorageService sessionStorage

<PageTitle>Counter</PageTitle>

<h1>Counter</h1>

<p role="status">Current count: @currentCount</p>

<button class="btn btn-primary" @onclick="IncrementCount">Click me</button>

@code {
    private int currentCount = 0;

    protected override async Task OnInitializedAsync()
    {
        currentCount = await sessionStorage.GetItemAsync<int>("count");
    }

    private void IncrementCount()
    {
        currentCount++;
        sessionStorage.SetItemAsync("count", currentCount);
    }
}

Blazor Server の時と同様にデータの保存、読み込みができます。(Blazored を利用した場合は、OnInitializedAsync でも読み込みが可能なようです。) ただし、そのままではデータの暗号化はされないので、ユーザーが自由にデータの中身を確認できる点については注意してください。

image.png

localStorage の場合

読み込むライブラリが違うだけで、ほとんど同じように実装できます。

using Blazored.LocalStorage;
using BlazorWasmBrowserStorage1;
using Microsoft.AspNetCore.Components.Web;
using Microsoft.AspNetCore.Components.WebAssembly.Hosting;

var builder = WebAssemblyHostBuilder.CreateDefault(args);
builder.RootComponents.Add<App>("##app");
builder.RootComponents.Add<HeadOutlet>("head::after");

builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) });
builder.Services.AddBlazoredLocalStorage();

await builder.Build().RunAsync();
@page "/counter"
@inject Blazored.LocalStorage.ILocalStorageService localStorage

<PageTitle>Counter</PageTitle>

<h1>Counter</h1>

<p role="status">Current count: @currentCount</p>

<button class="btn btn-primary" @onclick="IncrementCount">Click me</button>

@code {
    private int currentCount = 0;

    protected override async Task OnInitializedAsync()
    {
        currentCount = await localStorage.GetItemAsync<int>("count");
    }

    private void IncrementCount()
    {
        currentCount++;
        localStorage.SetItemAsync("count", currentCount);
    }
}

まとめ

Blazor で Web Storage を利用する方法をご紹介しました。 ページ遷移でデータを保持するだけであれば、サービスをDIコンテナに Scoped で登録することでも対応可能ですが、ページリロード時にはデータが消失します。その場合でもデータを保持したい場合には、Web Storage を利用をご検討ください。 皆様のご参考になれば幸いです。

参考サイト

この記事は以下の情報を参考にして執筆しました。 - https://docs.microsoft.com/ja-jp/aspnet/core/blazor/state-management?view=aspnetcore-6.0&pivots=server##browser-storage-server

技術サポート・無料オンライン相談会をご利用ください

インフラジスティックスのUI製品は多くの機能を備えているためドキュメントの情報量も多く、なかなかお探しの情報に辿り着けない場合もあります。そういった際はお気軽に技術サポートや、製品導入支援担当との無料オンライン相談会をご予約いただくことで検証時間を節約可能ですので、ぜひご活用ください。
技術サポートへの問い合わせ方法を確認する
無料オンライン相談会を予約する