Razor Pagesアプリケーションを作成しよう(3)
データのバインディング
ここまでで、Razor Pagesの最も基本的な実装をすることができました。次は、画面からデータをフォームで送信するケースを通して、Razor Pagesのデータバインディングの機能を確認します。
先ほど作成したページモデルクラス(Index.cshtml.cs)をリスト5の通り修正します。
using System;
using Microsoft.AspNetCore.Mvc; // 追加
using Microsoft.AspNetCore.Mvc.RazorPages;
namespace Sample.RazorPages.Pages
{
public class IndexModel : PageModel
{
public string Message { get; set; }
// 追加
[BindProperty]
public string Name { get; set; }
public IndexModel() {}
public void OnGet()
{
var now = DateTime.Now.ToString();
Message += $"現在時刻: {now}";
}
// 追加
public IActionResult OnPost()
{
Console.WriteLine($"入力された名前は:{Name} です。");
return Page();
}
}
}
ここではNameプロパティとOnPostメソッドを追加しました。Nameプロパティには[BindProperty]という属性を付与しています。この属性を付与することでページでのプロパティ値の変更を、ページモデル側で通常のプロパティ参照と同じようにアクセスすることができます。OnPostメソッドはHTTPのPOSTリクエストに対応するメソッドです。ここでは、リクエストを受信したら送信されたデータをコンソール上に出力する処理と、Indexページを再度表示する処理のみを記述しています。
次に、フォーム送信を行えるようにページを修正します。
@page
@model IndexModel
@namespace Sample.RazorPages.Pages
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
<h2>Razor Pages Sample トップページ</h2>
<p>
@Model.Message
</p>
<form method="post">
<div>Name: <input asp-for="@Model.Name" /></div>
<input type="submit" />
</form>
<div>
@Model.Name
</div>
ページでは、formタグとdivタグのブロックとaddTagHelperディレクティブを追加しました。addTagHelperディレクティブでは、タグヘルパーと呼ばれるHTML内でC#コードを記述するためのユーティリティの使用を宣言しています。ここでは、inputタグで「asp-for」というタグヘルパーを使用しています。これは、値に記述したプロパティの内容を画面にレンダリングしたり、画面から入力したデータをサーバに送信する際のパラメータとして使用されたりします。今回は後者の用途で利用しています。
ここまで実装したら、また「dotnet run」でアプリケーションを起動しましょう。画面に入力フォームとボタンが新たに表示されていると思います。入力フィールドに何か入力して送信ボタンを押してください。図5の通り入力した内容が画面に表示されていれば成功です。
また、コンソール上にも図6のように入力内容が表示されていることと思います。
改めてページモデルクラスのOnPostメソッドを見ると、メソッドの引数には何も指定がありません。しかしながら入力データがサーバに送られてブラウザやコンソールに出力されています。これを実現しているのがNameプロパティに付与している[BindProperty]属性です。このように、Razor Pagesではデータバインディングと呼ばれる仕組みを用いてページとページモデルをつなぎ、クライアントとサーバ間でのデータのやり取りを実現します。
レイアウトの適用
ここまではRazor Pagesの仕組みにフォーカスするため、画面のデザインについては必要最小限のもので実装を行いました。実際のアプリケーション開発では、各画面に共通のレイアウトを適用させることでデザインに統一性を持たせたり、生産性の向上を図ったりすることが必要となります。ASP.NETでは以前よりレイアウトの部品化や階層化のための仕組みが用意されており、それはRazor Pagesでも利用することができます。
Razor Pagesのアプリケーションに共通のレイアウトを適用させるためには、「_Layout.cshtml」と「_ViewStart.cshtml」の2つのファイルを「Pages」ディレクトリの配下に作成します。
<!DOCTYPE html>
<html>
<head>
<title>Razor Pages サンプル</title>
</head>
<body>
@RenderBody()
</body>
</html>
「_Layout.cshtml」には各ページ共通で適用したいレイアウトをHTML形式で記述します。「@RenderBody()」というディレクティブで指定した箇所に各画面のHTMLが埋め込まれます。
このレイアウトページをアプリケーションで有効化するためには、「_ViewStart.cshtml」ファイルでレイアウトページを宣言します。
@{
Layout = "_Layout";
}
以上の2つのファイルによってレイアウトの共通化を実現することができます。この仕組みはASP.NET Core MVCにも存在しますが、ファイルの配置場所が異なるためご注意ください(MVCの場合は「Views/Shared」ディレクトリに配置)。
また、「_ViewImports.cshtml」というファイルを同様に「Pages」ディレクトリの配下に作成し、共通的に使用するディレクティブをここに記述することで、各ページでの記述を減らすこともできます。
@namespace Sample.RazorPages.Pages @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
この例では、名前空間の宣言と使用するタグヘルパーの宣言を「_ViewImports.cshtml」ファイルに記述しています。これによって先ほど作成した「Index.cshtml」から同じ内容のディレクティブを削除しても、アプリケーションを動作させることができます。
おわりに
今回はASP.NET Core 2.0から新たに追加されたRazor Pagesについて、簡単なコードサンプルを題材に説明をしました。次回はJavaScriptフレームワークを用いる、SPAテンプレートによるWebアプリケーションの作成方法について説明します。
