LoginSignup
0
2

【ASP .NET】Todoリスト風の画面を作りながらrazor構文の基礎を確認する

Last updated at Posted at 2024-01-13

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>

こんな感じ
image.png

開発者ツールから実際の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操作よりは簡潔に見通し良く書けますね。

こんな感じ
image.png

@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>

こんな感じ
image.png

その他

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>

image.png

最後に

以上、razor構文の基本でした。
まだ学び始めたばかりで知らないことが多いですが、使っていて楽しいです。razor自体はそこそこ年季の入った技術ですが、今も十分にパワフルで便利だと思います。ドキュメントも充実してますし、やっぱり.NETは良いですね。

ちなみに、本記事の環境であるASP.NET MVC 5ですが、.NET Framework系のフレームワークなので、機能追加などは基本的にないです(多分)。
新規に自由な環境で学習する場合は、.NET Core系のASP.NET Core MVCがおすすめです。razor構文のページを少し見るだけでも、便利なものがいろいろ追加されてそうです。
https://learn.microsoft.com/ja-jp/aspnet/core/mvc/views/razor

0
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
2