前回の続きです。
前回は、超簡単なFormを、コントローラーとビューを使って作成しました。
今回は、MVCの「M」の要素、モデルを使ってみたいと思います。
コントローラーとビューがあれば一応動作するアプリは作れるのですが、モデルを使ってこそASP.NET Core MVCの真価を発揮します。
作るものは、前回と同じ、入力した文字を表示するだけの簡単なものです。
まず、Modelsフォルダを右クリックして、「追加 > クラス…」を選択してください。名前を「HelloModel.cs」としてください。
ファイルを開いて、1行追加します。
public class HelloModel { public string Name { get; set; } }
モデルはシンプルなクラスですので、必要なプロパティを追加します。
今回はNameというstringのプロパティを追加しました。
では、前回と同じくコントローラーを作成します。
Controllersを右クリックして、「追加 > コントローラー > MVCコントローラー – 空」を選択し、名称を「HelloController」としてください。
次にビューも用意します。
前回やったように、Viewsの下にコントローラー名のフォルダ「Hello」を作成します。
Helloフォルダを右クリックして、「追加 > 新規スキャフォールディングアイテム…」を選択してください。
「スキャフォールディングを追加」 の「共通 > MVC > ビュー」の下に「MVCビュー」という項目があります。「追加」をクリックして、
ビュー名:Index
テンプレート:Create
モデル クラス:HelloModel
を選択し、「追加」をクリックします。
すると、Index.cshtmlが生成されますので中身を見てみましょう。
@model AspNetCoreStudy.Models.HelloModel (略) <div class="row"> <div class="col-md-4"> <form asp-action="Index"> <div asp-validation-summary="ModelOnly" class="text-danger"></div> <div class="form-group"> <label asp-for="Name" class="control-label"></label> <input asp-for="Name" class="form-control" /> <span asp-validation-for="Name" class="text-danger"></span> </div> <div class="form-group"> <input type="submit" value="Create" class="btn btn-default" /> </div> </form> </div> </div> (略)
ということで、前回は手動で書いたFormタグまわりが、モデルを作成してスキャフォールディングすることによってあっという間に自動生成されました!
そして1行目に @model で始まる行があります。
これは、このcshtml(Razorページ)で使うモデルは、先ほど定義したHelloModelだよ、という指示になり、@Model.Nameの形でアクセスできるようになります。
そしてフォーム部分のHTMLですが、見慣れない構文が多数ありますね。「asp-action」とか、「asp-for」とか。これは、ASP.NETのヘルパータグというもので、サーバサイドで実行時に普通のHTMLタグに書き換えてくれます。ヘルパータグを自分で書こうと思うとかなりの習熟が必要ですが、必要なものを自動的に作ってくれるところもスキャフォールディングの便利なところです。
まずはこのまま実行して、/Hello/Indexを開いてみましょう。(前回のように、Startup.csを変更して、デフォルトページにしても構いません)
そこそこデザインの当たったフォームが開いたと思います。デザインはBootstrap(CSSフレームワーク)ですので、Bootstrapの知識があれば変更するのも簡単です。
では、せっかく定義した@modelに、実際にモデル(から作ったインスタンス)を渡してみます。HelloController.csのIndexメソッドを下記にしてみてください。また、Modelの名前空間を参照できるように、using句も追加すると便利です。
using AspNetCoreStudy.Models; (略) public IActionResult Index() { HelloModel helloModel = new HelloModel(); helloModel.Name = "名無しさん"; return View(helloModel); }
モデルクラスをインスタンス化して、return Viewの引数に設定することによって、ビューにインスタンスを渡すことができます。
これで実行すると、フォームに「名無しさん」が入った状態で表示されます。
HTML部分は何も変えていないのに不思議ですが、これがasp-forタグヘルパーの機能の一つになります。(type=”text”も自動的に出力されています)
Index.cshtmlのフォームの下あたりに、下記の行も追加してみてください。
<div>@Model.Name さんこんにちわ</div>
関連付けられたモデルのプロパティを表示しており、前回のようにViewData[“hoge”]を使った時よりも安全で確実なコードになっています。
実行すると下記になります。
次は、フォームからの情報を受け取るアクションを作成します。
下記のメソッドを追加します。
[HttpPost] public IActionResult Index(HelloModel helloModel) { return View(helloModel); }
まず注目すべきなのは、既存のIndexアクションと同じ名前で別のIndexアクションを追加できることです。ASP.NET MVCの重要な概念として、Routeの設定があります。今回の場合、[HttpPost]アトリビュートが存在するため、フォームからPOSTした時にはこちらのIndexアクションが優先して実行されます。
そして、引数がHelloModel型のインスタンスになっているところです。前回は、string型の引数を作成して、フォームからの情報はフレームワークが処理してくれた結果をstringとして受け取ることができました。
今回はさらに進歩して、フォームからの入力を紐づけたモデルのインスタンスの形で受け取ることができます。自分で引数を受け取ってインスタンスを生成するよりもずっと簡単で安全な仕組みになっています。
最終的にコードは下記になっています。
namespace AspNetCoreStudy.Models { public class HelloModel { public string Name { get; set; } } }
using Microsoft.AspNetCore.Mvc; using AspNetCoreStudy.Models; namespace AspNetCoreStudy.Controllers { public class HelloController : Controller { public IActionResult Index() { HelloModel helloModel = new HelloModel(); helloModel.Name = "名無しさん"; return View(helloModel); } [HttpPost] public IActionResult Index(HelloModel helloModel) { return View(helloModel); } } }
@model AspNetCoreStudy.Models.HogeModel @{ ViewData["Title"] = "Index"; } <h2>Index</h2> <h4>HogeModel</h4> <hr /> <div class="row"> <div class="col-md-4"> <form asp-action="Index"> <div asp-validation-summary="ModelOnly" class="text-danger"></div> <div class="form-group"> <label asp-for="Name" class="control-label"></label> <input asp-for="Name" class="form-control" /> <span asp-validation-for="Name" class="text-danger"></span> </div> <div class="form-group"> <input type="submit" value="Create" class="btn btn-default" /> </div> </form> </div> </div> <div>@Model.Name さんこんにちわ</div> <div> <a asp-action="Index">Back to List</a> </div>
うまく動きましたでしょうか?
モデルを起点としてコントローラー(今回は行っていませんが)やビューをスキャフォルドして、モデルをビューと紐づけて構築していく、というASP.NET Core MVCの流儀が少しでも伝わればと思います。
もっと作りたい方は前々回でご紹介した書籍などをご覧ください。