Note
これは、この記事の最新バージョンではありません。 現在のリリースについては、この記事の .NET 9 バージョンを参照してください。
重要
この情報はリリース前の製品に関する事項であり、正式版がリリースされるまでに大幅に変更される可能性があります。 Microsoft はここに示されている情報について、明示か黙示かを問わず、一切保証しません。
現在のリリースについては、この記事の .NET 9 バージョンを参照してください。
この記事は、映画データベースを管理する機能を備えた ASP.NET Core Blazor の構築の基本について説明する、Blazor Web App 映画データベース アプリ チュートリアルの第 4 部です。
チュートリアル シリーズのこの部分では、データベース コンテキストに焦点を当て、データベースのスキーマとデータを直接操作します。 データを使用したデータベースのシード処理についても説明します。
運用アプリに必要な安全な認証フロー
このチュートリアルでは、ユーザー認証が不要なローカル データベースを使用します。 運用アプリでは、使用可能な最も安全な認証フローを使用する必要があります。 デプロイされたテストおよび運用 Blazor Web App の認証の詳細については、次のリソースをご覧ください。
- ASP.NET Core Blazor の認証と認可
- ASP.NET Core Blazor 認証と承認 および Server セキュリティ ノードの次の記事
- OpenID Connect (OIDC) を使用して ASP.NET Core Blazor Web App をセキュリティで保護する
- Microsoft Entra ID を使用して ASP.NET Core Blazor Web App をセキュリティで保護する
Microsoft Azure サービスの場合は、マネージド ID を使用することをお勧めします。 マネージド ID を使用すると、アプリ コードに資格情報を保存せずに、Azure サービスに対して安全に認証を行うことができます。 詳細については、次のリソースを参照してください。
- Azure リソースのマネージド ID とは (Microsoft Entra のドキュメント)
- Azure サービスのドキュメント
データベース コンテキスト
データベース コンテキストである BlazorWebAppMoviesContext
は、データベースに接続し、モデル オブジェクトをデータベース レコードにマップします。 データベース コンテキストは、このシリーズの第 2 部で作成されました。 スキャフォールディングされたデータベース コンテキスト コードは、 Program
ファイルに表示されます。
builder.Services.AddDbContextFactory<BlazorWebAppMoviesContext>(options =>
options.UseSqlServer(
builder.Configuration.GetConnectionString("BlazorWebAppMoviesContext") ??
throw new InvalidOperationException(
"Connection string 'BlazorWebAppMoviesContext' not found.")));
builder.Services.AddDbContextFactory<BlazorWebAppMoviesContext>(options =>
options.UseSqlite(
builder.Configuration.GetConnectionString("BlazorWebAppMoviesContext") ??
throw new InvalidOperationException(
"Connection string 'BlazorWebAppMoviesContext' not found.")));
builder.Services.AddDbContextFactory<BlazorWebAppMoviesContext>(options =>
options.UseSqlite(
builder.Configuration.GetConnectionString("BlazorWebAppMoviesContext") ??
throw new InvalidOperationException(
"Connection string 'BlazorWebAppMoviesContext' not found.")));
AddDbContextFactory は、特定のコンテキストのファクトリをアプリのサービス コレクション内のサービスとして登録します。
UseSqlServer または UseSqlite は、Microsoft SQL Server または SQLite データベースに接続するようにコンテキストを構成します。 その他のプロバイダーは、追加の種類のデータベースに接続できます。
GetConnectionString は、ASP.NET Core 構成システムを使用して、指定された接続文字列名の ConnectionStrings
キーを読み取ります。これは、前の例では BlazorWebAppMoviesContext
です。
ローカルで開発する場合は、構成によってアプリ設定ファイル (appsettings.json
) からデータベース接続文字列が取得されます。 次の例の {CONNECTION STRING}
プレースホルダーは接続文字列です。
"ConnectionStrings": {
"BlazorWebAppMoviesContext": "{CONNECTION STRING}"
}
接続文字列の例を次に示します。
Server=(localdb)\mssqllocaldb;Database=BlazorWebAppMoviesContext-00001111-aaaa-2222-bbbb-3333cccc4444;Trusted_Connection=True;MultipleActiveResultSets=true
アプリがテスト/ステージング サーバーまたは運用サーバーに展開されている場合は、プロジェクトの構成ファイルの外部に接続文字列を安全に格納します。
警告
アプリ シークレット、接続文字列、資格情報、パスワード、個人識別番号 (PIN)、プライベート C#/.NET コード、秘密キー/トークンをクライアント側コードに格納しないでください。これは安全ではありません。 テスト/ステージング環境と運用環境では、サーバー側の Blazor コードと Web API は、プロジェクト コードまたは構成ファイル内で資格情報を維持しないように、セキュリティで保護された認証フローを使用する必要があります。 ローカル開発テスト以外では、環境変数が最も安全なアプローチではないため、環境変数を使用して機密データを格納しないようにすることをお勧めします。 ローカル開発テストでは、機密データをセキュリティで保護するために、 Secret Manager ツール をお勧めします。 詳細については、「 機密データと資格情報を安全に管理するを参照してください。
データベース テクノロジ
このチュートリアルの Visual Studio バージョンでは、SQL Server を使用します。
SQL Server Express LocalDB は、プログラム開発を対象にした、SQL Server Express データベース エンジンの軽量バージョンです。 LocalDB は要求時に開始され、ユーザー モードで実行されるため、複雑な構成はありません。 マスター データベース ファイル (*.mdf
) は C:/Users/{USER}
ディレクトリに配置されます。ここでは、{USER}
プレースホルダーはシステムのユーザー ID です。
[表示] メニューの [SQL Server オブジェクト エクスプローラー] (SSOX) を開きます。
Movie
テーブルを右クリックし、Movie
を選択します。
ビュー デザイナーが開きます。
ID
の横のキー アイコンに注意してください。 EF で主キーに ID
という名前のプロパティが作成されます。
Movie
テーブルを右クリックし、Movie
を選択します。
テーブルのデータが Visual Studio の新しいタブで開きます。
このチュートリアルの VS Code バージョンでは、SQLite を使用します。これは、パブリックで自己完結型のフル機能の SQL データベース エンジンです。
SQLite データベースを管理および表示するために使用できるサードパーティ製ツールは多数あります。 次の画像は、DB Browser for SQLite を示しています。
このチュートリアルでは、EF Core 移行を使用します。 移行では、データ モデルの変更に合わせてデータベース スキーマが更新されます。 ただし、移行は、 EF Core プロバイダーがサポートするデータベースにのみ変更を加えることができます。 詳細については、この記事の最後にリソースを示します。
このチュートリアルの VS Code バージョンでは、SQLite を使用します。これは、パブリックで自己完結型のフル機能の SQL データベース エンジンです。
SQLite データベースを管理および表示するために使用できるサードパーティ製ツールは多数あります。 次の画像は、DB Browser for SQLite を示しています。
このチュートリアルでは、EF Core 移行を使用します。 移行では、データ モデルの変更に合わせてデータベース スキーマが更新されます。 ただし、移行は、 EF Core プロバイダーがサポートするデータベースにのみ変更を加えることができます。 詳細については、この記事の最後にリソースを示します。
データベースのシード
シード処理コードは、開発テスト用のレコードのセットを作成したり、新しい運用データベースの初期データを作成するために使用したりできます。
SeedData
フォルダーに、次のコードで Data
という名前の新しいクラスを作成します。
Data/SeedData.cs
:
using Microsoft.EntityFrameworkCore;
using BlazorWebAppMovies.Models;
namespace BlazorWebAppMovies.Data;
public class SeedData
{
public static void Initialize(IServiceProvider serviceProvider)
{
using var context = new BlazorWebAppMoviesContext(
serviceProvider.GetRequiredService<
DbContextOptions<BlazorWebAppMoviesContext>>());
if (context == null || context.Movie == null)
{
throw new NullReferenceException(
"Null BlazorWebAppMoviesContext or Movie DbSet");
}
if (context.Movie.Any())
{
return;
}
context.Movie.AddRange(
new Movie
{
Title = "Mad Max",
ReleaseDate = new DateOnly(1979, 4, 12),
Genre = "Sci-fi (Cyberpunk)",
Price = 2.51M,
},
new Movie
{
Title = "The Road Warrior",
ReleaseDate = new DateOnly(1981, 12, 24),
Genre = "Sci-fi (Cyberpunk)",
Price = 2.78M,
},
new Movie
{
Title = "Mad Max: Beyond Thunderdome",
ReleaseDate = new DateOnly(1985, 7, 10),
Genre = "Sci-fi (Cyberpunk)",
Price = 3.55M,
},
new Movie
{
Title = "Mad Max: Fury Road",
ReleaseDate = new DateOnly(2015, 5, 15),
Genre = "Sci-fi (Cyberpunk)",
Price = 8.43M,
},
new Movie
{
Title = "Furiosa: A Mad Max Saga",
ReleaseDate = new DateOnly(2024, 5, 24),
Genre = "Sci-fi (Cyberpunk)",
Price = 13.49M,
});
context.SaveChanges();
}
}
依存関係挿入 (DI) コンテナーからデータベース コンテキスト インスタンスを取得します。 ムービーが存在する場合は、データベースのシード処理を回避するために return
が呼び出されます。 データベースが空の場合、Mad Max シリーズ (©Warner Bros. Entertainment) ムービーがシードされます。
シード初期化子を実行するには、アプリ (Program
) をビルドする行の直後に var app = builder.Build();
ファイルに次のコードを追加します。 using
ステートメントでは、シード処理の完了後にデータベース コンテキストが破棄されます。
using (var scope = app.Services.CreateScope())
{
var services = scope.ServiceProvider;
SeedData.Initialize(services);
}
データベースに以前のテストのレコードが含まれている場合は、アプリを実行し、データベースで作成したエンティティを削除します。 ブラウザーのウィンドウを閉じて、アプリを停止します。
データベースに以前のテストのレコードが含まれている場合は、アプリを実行し、データベースで作成したエンティティを削除します。 ブラウザーのウィンドウを閉じ、VS Code でキーボードの Shift+F5 キーを押して、アプリを停止します。
データベースに以前のテストのレコードが含まれている場合は、アプリを実行し、データベースで作成したエンティティを削除します。 ブラウザーのウィンドウを閉じ、コマンド シェルで Ctrl +C (Windows)押して、アプリを停止します。
データベースが空の場合は、アプリを実行します。
ムービー Index
ページに移動して、シード処理されたムービーを表示します。
フォームをモデルにバインドする
Edit
コンポーネント (Components/Pages/MoviePages/Edit.razor
) を確認します。
(たとえば、相対 URL: Edit
で) /movies/edit?id=6
コンポーネント ページに対して HTTP GET 要求が行われた場合
- OnInitializedAsync メソッドは、データベースから
Id
の6
を使用してムービーを取ってきて、Movie
プロパティに割り当てます。 - EditForm.Model パラメータは、フォームの最上位モデル オブジェクトを指定します。 割り当てられたモデルを使用して、フォームの編集コンテキストが構築されます。
- フォームには、ムービーからの値が表示されます。
Edit
ページがサーバーにポストされると、Movie
は [SupplyParameterFromForm]
プロパティで注釈が付いているため、ページのフォーム値は プロパティにバインドされます。
[SupplyParameterFromForm]
private Movie? Movie { get; set; }
フォームがポストされるときにモデルの状態にエラーがある場合 (たとえば、ReleaseDate
を日付に変換できない場合)、送信された値を含むフォームが再表示されます。 モデルのエラーが存在しない場合、ムービーはフォームのポストされた値を使用して保存されます。
コンカレンシーの例外処理
UpdateMovie
コンポーネント (Edit
) の Components/Pages/MoviePages/Edit.razor
メソッドを確認します。
private async Task UpdateMovie()
{
using var context = DbFactory.CreateDbContext();
context.Attach(Movie!).State = EntityState.Modified;
try
{
await context.SaveChangesAsync();
}
catch (DbUpdateConcurrencyException)
{
if (!MovieExists(Movie!.Id))
{
NavigationManager.NavigateTo("notfound");
}
else
{
throw;
}
}
NavigationManager.NavigateTo("/movies");
}
1 人のクライアントがムービーを削除し、別のクライアントがムービーに変更を投稿した場合に、コンカレンシーの例外を検出します。
前のコードによるコンカレンシーの処理方法をテストするには:
- ムービー用に Edit を選択し、変更を行います。ただし、Save は選択しないでください。
- 別のブラウザー ウィンドウで、ムービー
Index
ページにアプリを開き、同じムービーの Delete リンクを選択してムービーを削除します。 - 前のブラウザー ウィンドウで、Save ボタンを選択してムービーに変更をポストします。
- ブラウザーが
notfound
エンドポイントに移動します。このエンドポイントは存在せず、404 (Not Found) の結果になります。
EF Core アプリでの Blazor のコンカレンシーの処理に関するその他のガイダンスについては、Blazor ドキュメントをご覧ください。
アプリを停止する
アプリが実行されている場合は、ブラウザーのウィンドウを閉じてアプリをシャットダウンします。
アプリが実行されている場合は、ブラウザーのウィンドウを閉じ、VS Code でキーボードの Shift+F5 キーを押して、アプリをシャットダウンします。
アプリが実行されている場合は、ブラウザーのウィンドウを閉じ、コマンド シェルで Ctrl +C押して、アプリをシャットダウンします。
完成したサンプルを使用したトラブルシューティング
チュートリアルの実行中にテキストから解決できない問題が発生した場合は、コードを、 Blazor サンプル リポジトリの完成したプロジェクトと比較します。
Blazor サンプル GitHub リポジトリ (dotnet/blazor-samples
)
最新バージョンのフォルダーを選択します。 このチュートリアルのプロジェクトのサンプル フォルダーには、BlazorWebAppMovies
という名前が付けられています。
その他のリソース
- 構成に関する記事:
- ASP.NET Coreでの構成 (ASP.NET Core 構成システム)
- ASP.NET Core Blazor 構成 (Blazor ドキュメント)
- データ シード処理 (EF Core ドキュメント)
- EF Core アプリでの Blazor とのコンカレンシー
- データベース プロバイダー リソース:
- Blazor Web App セキュリティ
法的情報
Mad Max、The Road Warrior、Mad Max: Beyond Thunderdome、Mad Max: Fury Road、Furiosa: A Mad Max Saga は、Warner Bros. Entertainment の商標および著作物です。
次のステップ
ASP.NET Core