4
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

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

Last updated at Posted at 2022-01-17

この記事では、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の場合

CounterSessionStorage.razor
@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コンポーネントから利用できます。

Program.cs
using Blazored.SessionStorage;

...

builder.Services.AddBlazoredSessionStorage();

await builder.Build().RunAsync();
Counter.razor
@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の場合

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

Program.cs
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();
Counter.razor
@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を利用をご検討ください。
皆様のご参考になれば幸いです。

参考サイト

この記事は以下の情報を参考にして執筆しました。

4
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?