【ASP .NET】Todoリスト風の画面を作りながらrazor構文の基礎を確認する
Razor構文とは
ASP .NETやASP .NET Coreで使われるマークアップ構文です。
htmlとC#(あるいはVB)を織り交ぜたような記述が可能で、razorエンジンによってhtmlにコンパイルされます。主にcshtmlというファイルに記述され、基本はhtmlの文法に従い、C#の記述を用いたい場合にはrazor構文によってC#のコードブロックを作ります。
本記事の環境は、ASP .NET MVC 5です。
(Core じゃないですごめんなさい)
Razor構文入門
razor構文は@
で始めることができて、ざっくりと以下のような使用イメージです。
-
@
値を埋め込む
<p>@Model.var</p>
-
@()
式を埋め込む
<p>@(Model.var1 + Model.var2)</p>
-
@{}
複数行にわたる記述
<p>@Model.var1</p>
<p>@Model.var2</p>
-
@<キーワード>
各種ディレクティブ
キーワードによっていろいろな動作をさせられる
次項からは、簡易なTodoリストの初期表示を通して、各種ディレクティブを確認していきます。
(※ @
パターンは、実際には暗黙的に解釈させるだけなので、コンパイラから見てコードブロックの範囲が明らかなら式も書けます。)
@model
ディレクティブ
ASP .NET MVCではViewはControllerからModelを一つ受け取ります。その際に、どのModelクラスを受け取るのか宣言するための構文です。
まず、TodoListを返すだけのModelを用意して、Controllerでそのまま渡してみます。
Model
public class TodoListModel
{
public readonly TodoTask todoTask = new TodoTask( "taskA", true , new DateTime(2023, 12, 16)) ;
}
public class TodoTask
{
// タスク名
public string title;
// 完了したかどうか
public bool isComplete;
// 完了日
public DateTime? completeDate;
public TodoTask(string title, bool isComplete, DateTime? completeDate = null)
{
this.title = title;
this.isComplete = isComplete;
this.completeDate = completeDate;
}
}
Controller
public class TodoListController : Controller
{
// GET: TodoList
public ActionResult Index()
{
// TodoリストのModelを返す
return View(new TodoListModel());
}
}
そしてViewで@model
構文を用いると、受け取ったインスタンスをそのまま参照できます。
@model WebApplication1.Models.TodoListModel
<body>
<h2>Todo List</h2>
<ul>
<li>
<strong>@Model.todoTask.title</strong> -
<span>Completed (@Model.todoTask.completeDate.Value.ToShortDateString())</span>
</li>
</ul>
</body>
こんな感じ
開発者ツールから実際のhtmlを見てみると、モデルのプロパティがrazorエンジンによって実際の値で埋め込まれていることがわかります。
<strong>taskA</strong> -
<span>Completed (2023/12/16)</span>
@helper
ディレクティブ
HTMLのコードを再利用可能にするための仕組みです。モダンなフレームワークで見かけるコンポーネントのようなリッチな概念ではありません。純粋なHTMLの断片を切り出す仕組みです。
引数を受け取ることができますが、サーバサイドでレンダリングされるので値は静的にバインドされます。
例えば先ほどのViewの場合は、li
要素をこんな風に切り出して再利用できます。
<body>
<h2>Todo List</h2>
@using WebApplication1.Models
@helper DisplayTask(TodoTask todotask){
<li>
<strong>@todotask.title</strong> -
<span>Completed (@todotask.completeDate.Value.ToShortDateString())</span>
</li>
}
<ul>
// li要素が展開される
@DisplayTask(Model.todoTask)
</ul>
</body>
@for
ディレクティブ
繰り返しを記述するrazor構文です。
これまでの例では、そもそもModel側にタスクが一つしかなかったので、まずこれをリストにします。
Model
public class TodoListModel
{
public readonly List<TodoTask> taskList = new List<TodoTask>
{
new TodoTask( "taskA", true , new DateTime(2023, 12, 16)),
new TodoTask( "taskB", true , new DateTime(2023, 12, 17)),
};
}
こうするとViewは以下のように記載できます。for文自体は普段のC#と同じ文法です。ここではforeachを使ってますがforもあります。
View
<ul>
@foreach (var task in Model.taskList)
{
@DisplayTask(task)
}
</ul>
先ほど@using
ディレクティブで、DisplayTask()
として切り出したli
要素を繰り返しています。htmlのべた書きや素のjsのDOM操作よりは簡潔に見通し良く書けますね。
こんな感じ
@if
もちろん条件分岐もあります。Todoリストですから、未完のタスクにも対応できるようにします。
まず、Modelにcompleteじゃないタスクを追加しましょう。
Model
public class TodoListModel
{
public readonly List<TodoTask> taskList = new List<TodoTask>
{
new TodoTask( "taskA", true , new DateTime(2023, 12, 16)),
new TodoTask( "taskB", true , new DateTime(2023, 12, 17)),
// 未完了なタスクを追加
new TodoTask( "taskC", false ),
new TodoTask( "taskD", false ),
new TodoTask( "taskE", false )
};
}
次にhelperクラスを、isCompleteの状態に応じて分岐させます。
View
<body>
<h2>Todo List</h2>
@using WebApplication1.Models
@helper DisplayTask(TodoTask todotask){
<li>
<strong>@todotask.title</strong> -
// 分岐を追加
@if (todotask.isComplete)
{
<span>Completed (todotask.completeDate.Value.ToShortDateString())</span>
}
else
{
<span>Pending</span>
}
</li>
}
<ul>
@foreach (var task in Model.taskList)
{
@DisplayTask(task)
}
</ul>
</body>
こんな感じ
その他
razor構文の紹介をしてきましたが、これらはあくまで、htmlの世界とC#の世界を行き来するための構文です。
C#のブロックに入れば、LINQなども自由に使えます。
最後に、LINQを用いてリストを完了済みのものと、未完了なもので分別してみます。
<h3>Complet Task</h3>
<ul>
// 完了済みのアイテムだけ抽出して並べる
@foreach (var task in Model.taskList.Where(task => task.isComplete))
{
@DisplayTask(task)
}
</ul>
<h3>Incomplete Task</h3>
<ul>
// 未完了のアイテムだけ抽出して並べる
@foreach (var task in Model.taskList.Where(task => !task.isComplete))
{
@DisplayTask(task)
}
</ul>
最後に
以上、razor構文の基本でした。
まだ学び始めたばかりで知らないことが多いですが、使っていて楽しいです。razor自体はそこそこ年季の入った技術ですが、今も十分にパワフルで便利だと思います。ドキュメントも充実してますし、やっぱり.NETは良いですね。
ちなみに、本記事の環境であるASP.NET MVC 5ですが、.NET Framework系のフレームワークなので、機能追加などは基本的にないです(多分)。
新規に自由な環境で学習する場合は、.NET Core系のASP.NET Core MVCがおすすめです。razor構文のページを少し見るだけでも、便利なものがいろいろ追加されてそうです。
Discussion