🍣
ASP.NET Core Blazor でクエリパラメーターを駆使して状態保存
頭の体操みたいな感じなので、多分実プロジェクトではやらないと思うけど、やっちゃったのでメモ。
前提知識
.NET 6 ではクエリパラメーターをコンポーネントのパラメーターに簡単に設定できる機能が追加されているということが前提条件です。
やりたいこと
Blazor のプロジェクトの新規作成をしたときに作られるカウンターのページのカウントの値を画面遷移をしても保持し続けたい。
データの保存と復元処理は Counter コンポーネントには 書きたくない。DI コンテナにカウンターの値を管理するようなクラスを登録したりせずに、なるべくクエリパラメーターとかを駆使して、その値を何処かに持っておくような形にしたい。
やったこと
まずは、カウンターコンポーネントのカウンターの値をクエリパラメーターから設定できるようにします。
Counter.razor
@page "/counter"
@inject NavigationManager _navigationManager
<PageTitle>Counter</PageTitle>
<h1>Counter</h1>
<p role="status">Current count: @CurrentCount</p>
<button class="btn btn-primary" @onclick="IncrementCount">Click me</button>
@code {
[SupplyParameterFromQuery(Name = "count")]
[Parameter]
public int CurrentCount { get; set; }
private void IncrementCount()
{
CurrentCount++;
_navigationManager.NavigateTo(
_navigationManager.GetUriWithQueryParameter("count", CurrentCount),
replace: true
);
}
}
次に App.razor の Router
コンポーネントの画面遷移時のイベントの OnNavigateAsync
メソッドで画面遷移の URL を見て count パラメーターの値を保存・復元するような処理を追加します。
App.razor
@using Microsoft.AspNetCore.WebUtilities
@inject NavigationManager _navigationManager
<Router AppAssembly="@typeof(App).Assembly" OnNavigateAsync="OnNavigateAsync">
<Found Context="routeData">
<RouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)" />
<FocusOnNavigate RouteData="@routeData" Selector="h1" />
</Found>
<NotFound>
<PageTitle>Not found</PageTitle>
<LayoutView Layout="@typeof(MainLayout)">
<p role="alert">Sorry, there's nothing at this address.</p>
</LayoutView>
</NotFound>
</Router>
@code {
// とりあえずカウンターの値はここに保存しておく。
private int _count = 0;
private Task OnNavigateAsync(NavigationContext context)
{
if (context.Path.StartsWith("counter?"))
{
// count パラメーター付きの場合は値を保存
var uri = _navigationManager.ToAbsoluteUri(context.Path);
var parameters = QueryHelpers.ParseQuery(uri.Query); // Microsoft.AspNetCore.WebUtilities パッケージが必要
int.TryParse(parameters["count"].ToString(), out _count);
}
else if(context.Path == "counter" && _count != 0)
{
// counter ページへのパラメーター無しの遷移の場合は保存した値をパラメーターに足す
var path = _navigationManager.GetUriWithQueryParameter("count", _count);
_navigationManager.NavigateTo(path, replace: true);
}
return Task.CompletedTask;
}
}
こうすると、画面遷移時に count
パラメーター付きの時は、その値を App
クラスの _count
フィールドに保存しつつ、パラメーターの無い counter ページの遷移時には必要に応じて count
パラメーターをつけるようにしています。
とりあえず頭の体操的な感じですね。
Discussion