Blazor Server でセッション変数を使った処理のサンプルを作ったので参考にしてほしい。
ソースコードはGitHubで公開しています。
ソースコード構成
Visual Studio プロジェクト の Blazor Server テンプレートに、SessionKey.cs、LoginInfo.cs、SessionVariable_Class.razor、SessionVariable_Number.razor、SessionVariable_String.razor を追加し、NavMenu.razor、Startup.cs、_Imports.razor を修正しています。

ソースコード変更内容を解説
SessionKey.cs
・セッション変数のキー名を纏めている一般的な定数クラス。
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; namespace WebApplication1.Const {     public class SessionKey     {         public const string ClassInstance = "SessionKey_ClassInstance";         public const string Number = "SessionKey_Number";         public const string String = "SessionKey_String";     } } | 
LoginInfo.cs
・ログインユーザの情報を扱う一般的なModelクラス。
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; namespace WebApplication1.Model {     public class LoginInfo     {         public int UserId { set; get; }         public DateTime LoginDate { set; get; }     } } | 
_Imports.razor
・razorページ全体で使用する using のリストに、Microsoft.AspNetCore.Components.Server.ProtectedBrowserStorage を追加し、各razorページでセッション変数を扱えるようにしている。
・razorページ全体で定数クラス、データクラスを扱えるように、WebApplication1.Const、WebApplication1.Model も追加している。
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | @using System.Net.Http @using Microsoft.AspNetCore.Authorization @using Microsoft.AspNetCore.Components.Authorization @using Microsoft.AspNetCore.Components.Forms @using Microsoft.AspNetCore.Components.Routing @using Microsoft.AspNetCore.Components.Web @using Microsoft.AspNetCore.Components.Web.Virtualization @using Microsoft.AspNetCore.Components.Server.ProtectedBrowserStorage @using Microsoft.JSInterop @using WebApplication1 @using WebApplication1.Const @using WebApplication1.Model @using WebApplication1.Shared | 
Startup.cs
・services.AddSession(options => で、セッションに関係するクッキーを設定している。
 Nameでクッキー名を設定。
 IsEssentialでクッキーは必須と設定。
・app.UseSession() でセッション ミドルウェアを有効にしている。
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 | using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Components; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Http; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using WebApplication1.Data; namespace WebApplication1 {     public class Startup     {         public Startup(IConfiguration configuration)         {             Configuration = configuration;         }         public IConfiguration Configuration { get; }         // This method gets called by the runtime. Use this method to add services to the container.         // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940         public void ConfigureServices(IServiceCollection services)         {             services.AddRazorPages();             services.AddServerSideBlazor();             services.AddSingleton<WeatherForecastService>();             services.AddHttpContextAccessor();             services.AddSession(options =>             {                 options.Cookie.Name = "WebApplication1.Session.2021.demo";                 options.Cookie.IsEssential = true;             });         }         // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.         public void Configure(IApplicationBuilder app, IWebHostEnvironment env)         {             if (env.IsDevelopment())             {                 app.UseDeveloperExceptionPage();             }             else             {                 app.UseExceptionHandler("/Error");             }             app.UseStaticFiles();             app.UseRouting();             app.UseSession();             app.UseEndpoints(endpoints =>             {                 endpoints.MapBlazorHub();                 endpoints.MapFallbackToPage("/_Host");             });         }     } } | 
SessionVariable_Number.razor
・「セッション変数で数値型の値を扱う場合」画面。
・Microsoft.AspNetCore.Components.Server.ProtectedBrowserStorageをusingすることで使えるようになる @inject ProtectedSessionStorageで、_ProtectedSessionStoreメンバ変数を宣言し、SetAsync()、GetAsync()、DeleteAsync()メソッドでセッション変数を操作している。
・GetAsync()はセッション変数の型をジェネリックで指定する必要がある。ここではintを指定している。
・ GetAsync() の戻り値はProtectedBrowserStorageResultで、セッション変数の取得に成功したかを ProtectedBrowserStorageResult.Successで確認し、成功していればセッション変数の値を  ProtectedBrowserStorageResult.Value から取り出すことが出来る。
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 | @page "/SessionVariable_Number" @inject ProtectedSessionStorage _ProtectedSessionStore <h1>セッション変数で数値型の値を扱う場合</h1> <br /> <h3>セッション変数の値 : @_SessionVariable</h3> <br /> <button class="btn btn-primary" @onclick="SetSessionVariable">セッション変数に値を入力</button> <button class="btn btn-primary" @onclick="GetSessionVariable">セッション変数の値を出力</button> <button class="btn btn-primary" @onclick="DeleteSessionVariable">セッション変数の値を削除</button> @code {     private int? _SessionVariable;     private async Task SetSessionVariable()     {         // セッション変数に値を入力         await _ProtectedSessionStore.SetAsync(SessionKey.Number, 1);     }     private async Task GetSessionVariable()     {         _SessionVariable = null;         // セッション変数の値を出力         var result = await _ProtectedSessionStore.GetAsync<int>(SessionKey.Number);         if (result.Success)         {             // 該当するセッション変数が有るので、画面に表示する。             _SessionVariable = result.Value;         }     }     private async Task DeleteSessionVariable()     {         // セッション変数の値を削除         await _ProtectedSessionStore.DeleteAsync(SessionKey.Number);     } } | 
SessionVariable_String.razor
・「セッション変数で文字列型の値を扱う場合」画面。
・SessionVariable_Number.razor との違いは、GetAsync()でセッション変数の型にstringを指定しているのみ。
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 | @page "/SessionVariable_String" @inject ProtectedSessionStorage _ProtectedSessionStore <h1>セッション変数で文字列型の値を扱う場合</h1> <br /> <h3>セッション変数の値 : @_SessionVariable</h3> <br /> <button class="btn btn-primary" @onclick="SetSessionVariable">セッション変数に値を入力</button> <button class="btn btn-primary" @onclick="GetSessionVariable">セッション変数の値を出力</button> <button class="btn btn-primary" @onclick="DeleteSessionVariable">セッション変数の値を削除</button> @code {     private string? _SessionVariable;     private async Task SetSessionVariable()     {         // セッション変数に値を入力         await _ProtectedSessionStore.SetAsync(SessionKey.String, "A");     }     private async Task GetSessionVariable()     {         _SessionVariable = null;         // セッション変数の値を出力         var result = await _ProtectedSessionStore.GetAsync<string>(SessionKey.String);         if (result.Success)         {             // 該当するセッション変数が有るので、画面に表示する。             _SessionVariable = result.Value;         }     }     private async Task DeleteSessionVariable()     {         // セッション変数の値を削除         await _ProtectedSessionStore.DeleteAsync(SessionKey.String);     } } | 
SessionVariable_Class.razor
・「セッション変数でクラス型の値を扱う場合」画面。
・ SessionVariable_Number.razor との違いは、 SetAsync()にLoginInfoユーザー定義クラスのインスタンスを渡し、GetAsync()でセッション変数の型に LoginInfoユーザー定義クラス を指定しているのみ。 
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 | @page "/SessionVariable_Class" @inject ProtectedSessionStorage _ProtectedSessionStore <h1>セッション変数でクラス型の値を扱う場合</h1> <br /> <h3>セッション変数の値 : @_SessionVariable</h3> <br /> <button class="btn btn-primary" @onclick="SetSessionVariable">セッション変数に値を入力</button> <button class="btn btn-primary" @onclick="GetSessionVariable">セッション変数の値を出力</button> <button class="btn btn-primary" @onclick="DeleteSessionVariable">セッション変数の値を削除</button> @code {     private string? _SessionVariable;     private async Task SetSessionVariable()     {         var loginInfo = new LoginInfo()         {             UserId = 1,             LoginDate = DateTime.Now         };         // セッション変数に値を入力         await _ProtectedSessionStore.SetAsync(SessionKey.ClassInstance, loginInfo);     }     private async Task GetSessionVariable()     {         _SessionVariable = null;         // セッション変数の値を出力         var result = await _ProtectedSessionStore.GetAsync<LoginInfo>(SessionKey.ClassInstance);         if (result.Success)         {             // 該当するセッション変数が有るので、画面に表示する。             _SessionVariable = "UserId : " + result.Value.UserId + " LoginDate : " + result.Value.LoginDate.ToString();         }     }     private async Task DeleteSessionVariable()     {         // セッション変数の値を削除         await _ProtectedSessionStore.DeleteAsync(SessionKey.ClassInstance);     } } | 
NavMenu.razor
SessionVariable_Number.razor、SessionVariable_String.razor、SessionVariable_Class.razor 画面へのリンクを追加したのみ。
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 | <div class="top-row pl-4 navbar navbar-dark">     <a class="navbar-brand" href="">WebApplication1</a>     <button class="navbar-toggler" @onclick="ToggleNavMenu">         <span class="navbar-toggler-icon"></span>     </button> </div> <div class="@NavMenuCssClass" @onclick="ToggleNavMenu">     <ul class="nav flex-column">         <li class="nav-item px-3">             <NavLink class="nav-link" href="" Match="NavLinkMatch.All">                 <span class="oi oi-home" aria-hidden="true"></span> Home             </NavLink>         </li>         <li class="nav-item px-3">             <NavLink class="nav-link" href="counter">                 <span class="oi oi-plus" aria-hidden="true"></span> Counter             </NavLink>         </li>         <li class="nav-item px-3">             <NavLink class="nav-link" href="fetchdata">                 <span class="oi oi-list-rich" aria-hidden="true"></span> Fetch data             </NavLink>         </li>         <li class="nav-item px-3">             <NavLink class="nav-link" href="SessionVariable_Number">                 <span class="oi oi-plus" aria-hidden="true"></span> セッション変数 数値             </NavLink>         </li>         <li class="nav-item px-3">             <NavLink class="nav-link" href="SessionVariable_String">                 <span class="oi oi-plus" aria-hidden="true"></span> セッション変数 文字列             </NavLink>         </li>         <li class="nav-item px-3">             <NavLink class="nav-link" href="SessionVariable_Class">                 <span class="oi oi-plus" aria-hidden="true"></span> セッション変数 クラス             </NavLink>         </li>     </ul> </div> @code {     private bool collapseNavMenu = true;     private string NavMenuCssClass => collapseNavMenu ? "collapse" : null;     private void ToggleNavMenu()     {         collapseNavMenu = !collapseNavMenu;     } } | 
注意点
Blazor Server でセッション変数を使用する場合 WebSocketが必須
Visual Studio プロジェクト
今回使った Visual Studio プロジェクト テンプレートは、Blazor Server 5.0 の認証無し、HTTPS無しです。


 
  
  
  
  

コメント