カテゴリを登録するフォームを作成
Createメソッドを作成してからViewファイルを作成。
ビューファイル名はメソッド名と一致する必要があるので注意。
追加を押す。
return View(new Category);として新しいカテゴリーをビューに渡してもいいんだけど、何も渡さなくてもビューファイルで@model Categoryとカテゴリーを定義していれば新しいカテゴリーのオブジェクトが作成されるので問題ない。
@model Category <div class="row pt-2"> <div class="col-6"> <h1>カテゴリー</h1> </div> </div> <form method="post"> <div class="form-group"> <label asp-for="Name"></label> <input asp-for="Name" class="form-control" placeholder="カテゴリー名"> </div> <div class="form-group mb-3"> <label asp-for="DisplayOrder"></label> <input asp-for="DisplayOrder" class="form-control" placeholder="表示順序"> </div> <button type="submit" class="btn btn-outline-primary">追加</button> <a asp-controller="Category" asp-action="Index" class="btn btn-secondary">一覧に戻る</a> </form>
asp-forのInput Tag Helperにはカテゴリーモデルで定義されたプロパティしか指定できないので注意。
なので、例えばNameTestとするとエラーになる。
それとasp-forがあればタイプを定義する必要がなく、プロパティ名から自動的にタイプを検索する。
カテゴリーモデルのNameプロパティに[DisplayName("カテゴリー名")]のデータアノテーションを追加してビルドすれば、ラベルにカテゴリー名と表示できる。
追加しない場合はデフォルトではNameと表示される。
登録処理を作成
[HttpPost] public IActionResult Create(Category obj) { _db.Categories.Add(obj); _db.SaveChanges(); return RedirectToAction("Index","Category"); }
カテゴリーを追加したら、Indexメソッドにリダイレクトする。
バリデーションを作成
まずはサーバー側のバリデーションを追加していく。モデルにデータアノテーションを追加する。
条件分岐を追加してバリデーションに引っかかると、ModelState(Categoryオブジェクトのこと).IsValidがfalseになる。
モデルに定義したエラーメッセージを表示させるにはasp-validation-forを使う。
クライアント側のバリデーションを追加したい場合は、@Scriptsの処理を追加する。これを追加することによってエラーがある場合はクライアント側でエラーを表示してくれるので画面のリロードが実行されないで済む。
編集機能を作成
リンクを呼び出すときに、ID を渡すにするにはasp-route-idを使う。
public IActionResult Edit(int? id) { if (id == null || id == 0) { return NotFound(); } Category? categoryFromDb = _db.Categories.Find(id); //Category? categoryFromDb1 = _db.Categories.FirstOrDefault(u=>u.Id==id); //Category? categoryFromDb2 = _db.Categories.Where(u=>u.Id==id).FirstOrDefault(); if (categoryFromDb == null) { return NotFound(); } return View(categoryFromDb); } [HttpPost] public IActionResult Edit(Category obj) { if (ModelState.IsValid) { _db.Categories.Update(obj); _db.SaveChanges(); TempData["success"] = "更新しました"; return RedirectToAction("Index"); } return View(); }
ここで大事なのはデータベースから編集したいレコードを取得し、それをビューに渡すこと。
@model Category <div class="row pt-2"> <div class="col-6"> <h1>カテゴリー編集</h1> </div> </div> <form method="post"> <div class="form-group"> <label asp-for="Name"></label> <input asp-for="Name" class="form-control" placeholder="カテゴリー名"> <span asp-validation-for="Name" class="text-danger"></span> </div> <div class="form-group mb-3"> <label asp-for="DisplayOrder"></label> <input asp-for="DisplayOrder" class="form-control" placeholder="表示順序"> <span asp-validation-for="DisplayOrder" class="text-danger"></span> </div> <button type="submit" class="btn btn-outline-success">編集</button> <a asp-controller="Category" asp-action="Index" class="btn btn-secondary">一覧に戻る</a> </form> @section Scripts{ @{ <partial name="_ValidationScriptsPartial" /> } }
データのIdを送信する以下のInputがないやんと気づいた人もいるかもしれないけど、これは必須ではない。
<input asp-for="Id" hidden />
じゃあどうやってどのIdのレコードを更新するのが分かるのっていう話なんだけど、↑がなくてもコントローラー側にポストされるオブジェクトにはちゃんとIdの値が含まれているみたい。
削除機能を作成
public IActionResult Delete(int? id) { if (id == null || id == 0) { return NotFound(); } Category? categoryFromDb = _db.Categories.Find(id); if (categoryFromDb == null) { return NotFound(); } return View(categoryFromDb); } [HttpPost, ActionName("Delete")] public IActionResult DeletePost(int? id) { Category? obj = _db.Categories.Find(id); if (obj == null) { return NotFound(); } _db.Categories.Remove(obj); _db.SaveChanges(); TempData["success"] = "削除しました"; return RedirectToAction("Index"); }
次に削除機能を追加していく。
アクションメソッドに同じ名前を付けてない理由はget と post でパラメータが同じの場合は同じメソッド名にできないみたい。だから、postの方はDeletePostという名前にする。
余談だがフォームで削除ボタン押したら処理の中で delete アクション メソッドが検索されるみたい。エンドポイントのアクション名が DeletePost になっているからフォームでDeletePostのアクション メソッドが実行されるように指定しなくてもDeletePostが実行されるようになってるみたい。
@model Category <div class="row pt-2"> <div class="col-6"> <h1>カテゴリー削除 </h1> </div> </div> <form method="post"> <input asp-for="Id" hidden /> <div class="form-group"> <label asp-for="Name"></label> <input asp-for="Name" class="form-control" disabled placeholder="カテゴリー名"> </div> <div class="form-group mb-3"> <label asp-for="DisplayOrder"></label> <input asp-for="DisplayOrder" class="form-control" disabled placeholder="表示順序"> </div> <button type="submit" class="btn btn-outline-danger">削除</button> <a asp-controller="Category" asp-action="Index" class="btn btn-secondary">一覧に戻る</a> </form>
成果物
成果物は以下。