你的浏览器还没开启 Javascript 功能!

ASP.NET Core 入門5 ASP.NET Core MVC ビューエンジンRazor

前回に引き続きASP.NET Coreを学習メモです。今回はASP.NET Core MVC の規定ビューエンジンのRazorの基礎について学んでいきます。

前提

1. このコンテンツを扱うこと

  • Razorの概要
  • RazorのViewDataの概要と使用例
  • RazorのViewBagの概要と使用例
  • RazorのViewModelの概要と使用例

2. 環境情報

環境/ソフトウェア内容
オペレーティングシステムWindows 10 1903
.NET Core SDK2.1.801
IDEVisual Studio Code 1.37.1
BrowserGoogle Chrome 76.0.3809.132

3. 前提知識

ASP.NET Core MVC Razor

1. Razorとは

ASP.NET Core MVCのRazor(ビューエンジン)はHTML形式のテンプレートを表現するために使用されるマークアップ言語です。
RazorはView関数の呼び出しによって起動され、拡張子cshtmlファイルが最終的にHTMLレイアウトで表示されるデータを含んだビューモデルオブジェクトを返します。

Razorの中でC#でコードを記述でき、.NET開発者にとって親和性が高いです。

JavaのSpringで例えるならThymeleaf, Freemarker

2. Razorレイアウトテンプレート

ASP.NET Coreプロジェクトには通常Viewsというフォルダがあり、Razorのテンプレートはその配下に配置します。

  • 例) ~/Views/Home/Index.cshtml

各テンプレートの配置先は使用するコントローラーの名前が付いたフォルダでなければなりません。
Controllerでreturn View(); を指定した場合、MVCフレームワークは以下の順序でテンプレートエンジンを検索します。

  1. Views/[ControllerName]/[ViewName(ActionName)].cshtml
  2. Views/Shared/[ViewName(ActionName)].cshtml
  • 暗黙指定

    ViewNameを何も指定しない場合、ActionName=”Index”でcshtmlを検索します。

public class HomeController : Controller {
    public IActionResult Index () {
        return View();
    }
}
  • ViewNameを指定

    ViewNameを”ABC”で指定した場合、Views/Home/ABC.cshtmlでcshtmlを検索します。

public class HomeController : Controller {
    public IActionResult Index () {
        return View("ABC");
    }
}
  • 明確指定

    この場合、指定したファイルパスで検索します。

public class HomeController : Controller {
    public IActionResult Index () {
        return View("Views/Test/Index.cshtml");
    }
}

Razorを使ったデータバインディング

Razorビューにデータ渡すには3つの方法があり、2つの組込ディクショナリ(ViewData, ViewBag)、もしくは強く型指定されたViewModelを使用します。

@injectディレクティブという方法もありますが、あんまり一般的ではないのでここで特段扱いません。

3つの方法いずれもデータバインディングの機能を実現できますし、パフォーマンスに関してもごくわずかな差です。
しかし、設計、保守性観点ではViewModelを使用するほうがMicrosoftから強く推奨されています。

1. 準備作業

Controllersフォルダ配下でRenderDataControllerを作成します。

using System;
using ds.Tutorial.web.Models;
using Microsoft.AspNetCore.Mvc;

namespace ds.Tutorial.web.Controllers {
    public class RenderDataController : Controller {

    }

Viewsの配下にRenderDataのフォルダを作成します。

2. ViewDataディクショナリ

ViewDataは典型的な名前と値のペアからなるディクショナリです。

  • ViewDataDictionaryからの派生なので、ContainsKey, Add, Remove, Clearの属性が使用できます
  • キーペアなので、キーに空白は許可する ViewData[ "dongsu" ]
  • string以外のデータ型はRazorで表示する際は、コンバートする必要あります。

RenderDataControllerでViewDataDemoアクションメソッドを作成します。

public IActionResult ViewDataDemo () {
    ViewData["title"] = "ViewData Demo";
    ViewData["name"] = "dongsu";
    ViewData["birthday"] = new DateTime (2000, 3, 10);
    ViewData["hobby"] = new string[] { "筋トレ", "映画鑑賞", "Coding" };
    return View ();
}

Viewsの配下にRenderDataのフォルダの配下にViewDataDemo.cshtmlを作成します。

@{
    var hobby = ViewData["hobby"] as string[];
}

<h3>@ViewData["title"]</h3>

<ul>
    <li>名前: @ViewData["name"]</li>
    <li>誕生日: @ViewData["birthday"]</li>
    <li>趣味: @hobby[0], @hobby[1], @hobby[2]</li>
</ul>

F5でアプリ起動し、/renderdata/viewdatademo へアクセスを行うと、下記の画面が表示されます。

3. ViewBagオブジェクト

ViewBagもController基底クラスで定義され、その内容がビュークラスに自動的に書き込まれるプロパティです。

  • DynamicViewDataからの派生。@ViewBag.SampleKey= のように使用できる
  • ViewBagのほうが若干早い
  • ViewBagのほうがNULL検知しやすい、@ViewBag.Person?.Name

RenderDataControllerでViewBagDemoアクションメソッドを作成します。

public IActionResult ViewBagDemo () {
    ViewBag.title = "ViewBag Demo";
    ViewBag.name = "dongsu";
    ViewBag.birthday = new DateTime (2000, 3, 10);
    ViewBag.hobby = new string[] { "筋トレ", "映画鑑賞", "Coding" };
    return View ();
}

Viewsの配下にRenderDataのフォルダの配下にViewBagdemo.cshtmlを作成します。

@{
    var hobby = ViewBag.hobby as string[];
}

<h3>@ViewBag.title</h3>

<ul>
    <li>名前: @ViewBag.name</li>
    <li>誕生日: @ViewBag.birthday</li>
    <li>趣味: @hobby[0], @hobby[1], @hobby[2]</li>
</ul>

F5でアプリ起動し、/renderdata/viewbagdemo へアクセスを行うと、下記の画面が表示されます。

4. 強く型指定ViewModel

ViewData, ViewBagより厳密に型指定されるのがViewModelです。Razorの中で@modelでクラスをし、Modelのキーワード使うことでデータ表示できます。

Microsoftがもっとも推奨されるやり方です。(大事なことなので、2回言います)

Modelsフォルダ配下のPersonクラスを下記のように修正します。

using System;

namespace ds.Tutorial.web.Models {
    public class Person {
        public string Name { get; set; }
        public int Age { get; set; }
        public DateTime Birthday { get; set; }
        public string[] Hobby { get; set; }

    }
}

RenderDataControllerでViewModelDemoアクションメソッドを作成します。

public IActionResult ViewModelDemo () {
    ViewBag.title = "ViewModel Demo";
    var person = new Person {
        Name = "dongsu",
        Birthday = new DateTime (2000, 3, 10),
        Hobby = new string[] { "筋トレ", "映画鑑賞", "Coding" }

    };
    return View (person);
}

Viewsの配下にRenderDataのフォルダの配下にViewModeldemo.cshtmlを作成します。

@model ds.Tutorial.web.Models.Person;

<h3>@ViewBag.title</h3>

<ul>
    <li>名前: @Model.Name</li>
    <li>誕生日: @Model.Birthday</li>
    <li>趣味: @Model.Hobby[0], @Model.Hobby[1], @Model.Hobby[2]</li>
</ul>

F5でアプリ起動し、/renderdata/viewmodeldemo へアクセスを行うと、下記の画面が表示されます。

備考

今回作成したソースコードです。

GitHubリポジトリ

では!!( `ー´)ノ