概要
前回:ASP.NET Core MVCであみだくじを作ってみる 2 (ビュー,コントローラーの追加)
今回は、モデルを追加してビューと紐付けます。
モデルのデータを表示、編集し、別コントローラーへ移るところも作ります。
モデルを追加する
ソリューションエクスプローラーの「Models」を選択します。
右クリックでメニューを表示し、追加⇒クラスを選択します。
名前を「KujiModel.cs」にして追加します。
あみだくじには「タイトル」「くじ数」「結果(あたり、はずれ等)」があります。
それぞれ、データアノテーションの属性を付けて入力時に検証を行えるようにしておきます。
選択したくじ番号も作っておきます。コードは以下の通りです。
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
namespace Amidakuji.Models
{
/// <summary>
/// くじモデル
/// </summary>
public class KujiModel
{
// タイトル
[StringLength(20, ErrorMessage = "タイトルは20文字以内で入力してください")]
public string Title { get; set; }
// くじの数
[Range(1, 9, ErrorMessage = "1~9の数字を入力してください")]
public int NumberOfKuji { get; set; }
// くじの結果
public List<ResultModel> Result { get; set; }
// 選択したくじ番号
public int SelectId { get; set; }
/// <summary>
/// コンストラクタ
/// </summary>
public KujiModel() { }
}
/// <summary>
/// くじの結果モデル
/// </summary>
public class ResultModel
{
// 内容
[StringLength(5, ErrorMessage = "くじの結果は5文字以内で入力してください")]
public string Item { get; set; }
/// <summary>
/// コンストラクタ
/// </summary>
public ResultModel() { }
/// <summary>
/// コンストラクタ
/// </summary>
/// <param name="item"></param>
public ResultModel(string item)
{
Item = item;
}
}
}
ビューでモデルを利用できるようにする
Homeビューで上記モデルのデータを入力しようと思います。
Homeコントローラーでモデルのインスタンスを生成し、ビューに渡すように変更します。
using Amidakuji.Models;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using System.Collections.Generic;
using System.Diagnostics;
namespace Amidakuji.Controllers
{
public class HomeController : Controller
{
private readonly ILogger<HomeController> _logger;
public HomeController(ILogger<HomeController> logger)
{
_logger = logger;
}
public IActionResult Index()
{
// モデルのインスタンスを生成し、ビューに渡す
var model = new KujiModel();
model.Title = "晩御飯決定あみだくじ";
model.NumberOfKuji = 5;
model.Result = new List<ResultModel>()
{
new ResultModel("おでん"),
new ResultModel("湯豆腐"),
new ResultModel("シチュー"),
new ResultModel("ぶり大根"),
new ResultModel("ラーメン")
};
return View(model);
}
public IActionResult Privacy()
{
return View();
}
[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
public IActionResult Error()
{
return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });
}
}
}
ビューにデータを表示させてみます。
Home\Index.cshtmlを以下のように変更します。
ここでは、グリッドレイアウトを使ってみました。
@model Amidakuji.Models.KujiModel
@{
ViewData["Title"] = "あみだくじ";
}
<style>
/*あみだくじデータの設定領域*/
.kuji-items {
display: grid; /*グリッドレイアウトにする*/
grid-auto-columns: 100px; /*1列あたりの幅 100px*/
grid-auto-rows: 36px; /*1行あたりの高さ 30px*/
background-color: #99CCCC; /*背景色*/
margin: 0px auto; /*中央寄せ*/
padding:10px;
}
/*あみだくじデータの設定領域の入力項目*/
.kuji-items > input {
height: 30px; /*高さ*/
}
/*くじを作るボタン*/
.create_btn {
font-weight: bold;
padding: 0.25em 0.5em;
text-decoration: none;
color: #FFF;
background: #008080;
margin-left: 10px;
height: 30px; /*高さ*/
}
</style>
<form method="post" asp-controller="Home" asp-action="Index">
<div class="kuji-items">
<!--タイトル入力欄-->
<label style="grid-row:1;grid-column:1">タイトル : </label>
<input type="text" asp-for="Title" value="@Model.Title" style="grid-row:1;grid-column:2 / span 3" />
<!--くじの数入力欄-->
<label style="grid-row:2;grid-column:1">くじの数 : </label>
<input type="text" asp-for="NumberOfKuji" value="@Model.NumberOfKuji" style="grid-row:2;grid-column:2" />
<!--結果入力欄を増減するボタン-->
<button class="create_btn" style="grid-row:2;grid-column:5 / span 2" asp-route-name="set">結果を設定する</button>
<!--結果入力欄-->
<label style="grid-row:3;grid-column:1">結果 : </label>
@for (var i = 0; i < @Model.Result.Count; i++)
{
<input type="text" asp-for="Result[i].Item" value="@Model.Result[i].Item" style="grid-row:@(i + 3);grid-column:2 / span 3" />
}
<!--あみだくじ作成ボタン-->
<button class="create_btn" style="grid-row:@(Model.Result.Count + 2);grid-column:5 / span 2" asp-route-name="create">くじを作る</button>
<!--入力エラー表示欄-->
<div asp-validation-summary="All" class="text-danger" style="grid-row:@(Model.Result.Count + 3);grid-column:2 / span 5"></div>
</div>
</form>
1行目の「@model Amidakuji.Models.KujiModel」で、
このビューはKujiModelを使いますよ、という宣言になります。
KujiModelのプロパティに「@Model.xxx」でアクセスできるようになります。
詳しくは、ASP.NET Core の Razor 構文リファレンスに書かれています。
途中で、@forと書かれた行があります。
このように、Razorでは@記号によってC#のコードを埋め込むことができます。
ボタンを押した時にPOSTしたいので、formタグを使います。
formタグは、Webサーバーに情報を送信するための送信ボタンなどを含める区間です。
htmlタグについてはこちら
formタグのasp-controller、asp-actionは、ASP.NETのタグヘルパーです。
タグヘルパーについてはこちら
上記コードの場合、POSTでHomeControllerのIndexアクションを呼び出しますよ、という意味になります。
asp-controllerは、xxxControllerのxxxだけを指定します。
inputタグのasp-forは、入力タグヘルパーです。input要素をモデルにバインドします。
入力エラー表示欄のasp-validation-summaryは、検証タグヘルパーです。
モデルのプロパティに付けたデータアノテーション属性で入力値の検証を行い、エラーがあればメッセージを表示します。
POSTした時のアクションを追加する
上記のHomeコントローラーでは、POSTした時もIndex()が呼ばれます。
Index()はGET用として、新しくPOSTした時のIndexアクションを追加します。
HomeコントローラーのIndexを以下のように変更します。
[HttpGet]
public IActionResult Index()
{
// 新しいくじモデルをビューに渡す
var model = new KujiModel();
model.Title = "晩御飯決定あみだくじ";
model.NumberOfKuji = 5;
model.Result = new List<ResultModel>()
{
new ResultModel("おでん"),
new ResultModel("湯豆腐"),
new ResultModel("シチュー"),
new ResultModel("ぶり大根"),
new ResultModel("ラーメン")
};
return View(model);
}
/// <summary>
/// HomeビューでPOSTした時のアクション
/// </summary>
/// <param name="name"></param>
/// <param name="model"></param>
/// <returns></returns>
[HttpPost]
public IActionResult Index(string name, KujiModel model)
{
// 入力エラーがある時は何もしない
if (!ModelState.IsValid)
return View(model);
// [結果を設定する]ボタンを押下した場合
if (name == "set")
{
// くじの数が減った場合は、結果入力欄を減らす
while (model.NumberOfKuji < model.Result.Count)
{
model.Result.RemoveAt(model.Result.Count - 1);
}
// くじの数が増えた場合は、結果入力欄を増やす
while (model.NumberOfKuji > model.Result.Count)
{
model.Result.Add(new ResultModel());
}
return View(model);
}
// くじコントローラーを呼ぶ
return RedirectToAction("Index", "Kuji");
}
元々のIndex()には[HttpGet]を付け、GET用としました。
[HttpPost]を付けたIndexがPOSTで呼ばれるアクションになります。
パラメータの「string name」ですが、Home\Index.cshtmlのボタンにあるタグヘルパー「asp-route-name」で設定した"set"や"create"が渡されます。
パラメータ名とasp-route-xxxのxxx部分は同じである必要があります。xxx部分は自分で決めた文字列が使えます。
詳しくはこちら
また、パラメータの「KujiModel model」には、ビューで入力したデータを反映したモデルが渡されます。
最後に戻り値をRedirectToActionとしたのは、別コントローラー(くじコントローラー)のアクションに移りたいためです。
ViewとRedirectToActionの違いは、こちらの質問の回答を参考にしました。(自動翻訳なので少し変)
実行してみる
Homeを表示したところです。
モデルとビューの紐付けが出来ています。
くじの数に範囲外の数字を入力し、結果を設定するボタンを押下してみます。
データアノテーション検証が出来てます。
くじの数に範囲内の数字を入力し、結果を設定するボタンを押下してみます。
[HttpPost]を付けたIndexアクション内の処理が行われました。
くじを作るボタンを押下してみます。
Kujiビューに移りました。
まとめ
今回は、モデルを追加してビューと紐付けるところまでを行いました。
次回は、cssを使ってビューのレイアウトを作成します。
次回分はこちら⇒ASP.NET Core MVCであみだくじを作ってみる 4 (cssの作成)