Razor Pagesアプリケーションを作成しよう(2)
Razor Pagesページの作成
ASP.NET Coreでは実装するページは「cshtml」という拡張子のHTMLファイルとして作成します。これはRazor Pagesのアプリケーションでも同じです。Razor Pagesではさらに、ファイルの先頭に「pageディレクティブ」というRazor Pagesで実装したページであることを宣言する記述を追加する必要があります。
リスト3はアプリケーションのトップページとなるRazor Pagesページで、タイトルと現在時刻を表示するだけの非常に簡単なページです。プロジェクトのルートディレクトリに「Pages」という名前のディレクトリを作成し、その中に「Index.cshtml」ファイルを作成して編集します。
@page ・・・【1】
@model IndexModel ・・・【2】
@namespace Sample.RazorPages.Pages
@using Microsoft.AspNetCore.Mvc.RazorPages
@functions { ・・・【3】
public class IndexModel : PageModel ・・・【4】
{
public string Message { get; set; } ・・・【4】-1
public void OnGet() ・・・【4】-2
{
var now = DateTime.Now.ToString();
Message += $"現在時刻: {now}";
}
}
}
<h2>Razor Pages Sample トップページ</h2> ・・・【5】
<p>
@Model.Message ・・・【6】
</p>
構成要素についてそれぞれ説明します。
【1】pageディレクティブ
Razor Pagesのページには必ずpageディレクティブによる宣言が必要です。また、pageディレクティブはファイル内の最初のディレクティブである必要があります。
【2】ページモデルの宣言
このページで利用するページモデルの宣言をします。ここで宣言したページモデルは「@Model」としてページ内で参照することができるようになります。
【3】functionsディレクティブ
functionsディレクティブはクラスやメソッドを記述することができる領域です。通常のHTMLファイルにおけるscriptタグとその中のJavaScriptコードと同じ位置づけであると思ってください。ここではページモデルクラスを丸々functionsディレクティブ内で定義しています。
【4】ページモデルクラス
PageModelを継承したクラスで、クラス名は【2】に使用されます。ページモデルクラスにはページが使用することのできるプロパティ(【4】-1)やHTTPのリクエストに対応するハンドラーメソッド(【4】-2)などを実装します。HTTPに対応するハンドラーメソッドを実装するには、「On + <HTTPメソッド名>」の命名規則に沿ってメソッドを定義する必要があります。なお、メソッド内で非同期処理が必要な場合は、asyncキーワードを付与した非同期メソッドとしてメソッドを定義することも可能です。その際は慣例としてメソッド名の最後に「Async」を付けます。
【5】ビュー
画面に表示されるHTMLコードです。ページモデルの他、ASP.NET Core MVCと同様にタグヘルパーやHTMLヘルパーを使用することができます。
【6】ページモデルの使用
【4】で実装し、【2】で宣言したページモデルのインスタンスを「@Model」で参照しています。ここではMessageプロパティにアクセスしてプロパティが保持している値を表示しようとしています。
このIndex.cshtmlを保存して再度「dotnet run」を実行、ブラウザからアクセスしてみましょう。図4の通り、タイトルと現在時刻が表示されれば成功です。
Razor PagesでのURLルール
Pagesアプリケーションでは、Pagesディレクトリ配下のディレクトリ名とcshtmlファイル名によってURLが決定します。ページファイルの配置位置とURLが一致するため、URLの管理が非常に簡単になります。
例外として、各ディレクトリにあるIndex.cshtmlは「Index」を省略してアクセスすることができます。またPagesディレクトリ配下にあるIndex.cshtmlがアプリケーションのルートページとなります。
/Pages
┣ Index.cshtml ・・・「/」に対応
┗ /Animals
┣ Index.cshtml ・・・「/Animals」に対応
┣ Create.cshtml ・・・「/Animals/Create」に対応
┣ Edit.cshtml ・・・「/Animals/Edit」に対応
┗ /Dog
┣ Index.cshtml ・・・「/Animals/Dog」に対応
┗ Delete.cshtml ・・・「/Animals/Dog/Delete」に対応
ページとページモデルの分離
先ほど作成したIndex.cshtmlでは、ページモデルクラスをfunctionsディレクティブに記述していました。これは小規模なアプリケーションを素早く作成したい際に有用ですが、実際のアプリケーション開発ではcshtmlファイルが煩雑化していってしまうので、役割に応じてページとページクラスでファイルを分割しましょう。「Pages」ディレクトリの直下に「Index.cshtml.cs」というファイルを作成し、Index.cshtmlのfunctionsディレクティブに記載していたクラスを移し替えます。
using System;
using Microsoft.AspNetCore.Mvc.RazorPages;
namespace Sample.RazorPages.Pages
{
public class IndexModel : PageModel
{
public string Message { get; set; }
public IndexModel() {}
public void OnGet()
{
var now = DateTime.Now.ToString();
Message += $"現在時刻: {now}";
}
}
}
Index.cshtmlからは、functionsディレクティブとusingディレクティブの行(4行目)を削除します。この状態で「dotnet run」を実行して、先ほどと同じ結果が表示されれば成功です。
なお、ページモデルクラスには以下のルールがあるので覚えておきましょう。
- クラス名は「ページ名(ここではIndex)」 + 「Model」となること。
- ページモデルクラスはページと同じ名前空間に存在すること。
- ページモデルクラスを単体テストするためには、コンストラクタを明示的に記述する必要があること。
