2
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

【ASP.NET Core MVC】ASP.NET Core MVCであみだくじを作ってみる 3 (モデルの追加)

Last updated at Posted at 2019-11-04

概要

前回:ASP.NET Core MVCであみだくじを作ってみる 2 (ビュー,コントローラーの追加)
今回は、モデルを追加してビューと紐付けます。
モデルのデータを表示、編集し、別コントローラーへ移るところも作ります。

モデルを追加する

ソリューションエクスプローラーの「Models」を選択します。
右クリックでメニューを表示し、追加⇒クラスを選択します。
名前を「KujiModel.cs」にして追加します。

あみだくじには「タイトル」「くじ数」「結果(あたり、はずれ等)」があります。
それぞれ、データアノテーションの属性を付けて入力時に検証を行えるようにしておきます。
選択したくじ番号も作っておきます。コードは以下の通りです。

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コントローラーでモデルのインスタンスを生成し、ビューに渡すように変更します。

HomeController.cs
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を以下のように変更します。
ここでは、グリッドレイアウトを使ってみました。

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を以下のように変更します。

HomeController.cs
        [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を表示したところです。
1.PNG
モデルとビューの紐付けが出来ています。

くじの数に範囲外の数字を入力し、結果を設定するボタンを押下してみます。
2.PNG
データアノテーション検証が出来てます。

くじの数に範囲内の数字を入力し、結果を設定するボタンを押下してみます。
3.PNG
[HttpPost]を付けたIndexアクション内の処理が行われました。

くじを作るボタンを押下してみます。
4.PNG
Kujiビューに移りました。

まとめ

今回は、モデルを追加してビューと紐付けるところまでを行いました。
次回は、cssを使ってビューのレイアウトを作成します。
次回分はこちら⇒ASP.NET Core MVCであみだくじを作ってみる 4 (cssの作成)

2
5
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
2
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?