![]()
カテゴリを登録するフォームを作成

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>

成果物
成果物は以下。


