이전 글에서는 컨트롤러와 뷰를 작성해서 카테고리 테이블 안에 있는 데이터를 조회하는 기능을 만들었습니다.
이번 글에서는 뷰(페이지)에서 데이터를 Create를 할 수 있는 기능을 만들어 보려고 합니다.
우선 CategoryController 에서 카테고리 생성 페이지를 보여주기 위한 Create() 메서드를 생성해줍니다.
using BulkyBookWeb.Data;
using BulkyBookWeb.Models;
using Microsoft.AspNetCore.Mvc;
namespace BulkyBookWeb.Controllers
{
public class CategoryController : Controller
{
private readonly ApplicationDbContext _db;
public CategoryController(ApplicationDbContext db)
{
_db = db;
}
public IActionResult Index()
{
IEnumerable<Category> objCategoryList = _db.Categories.ToList();
return View(objCategoryList);
}
//GET, Create 메서드 추가
public IActionResult Create()
{
return View();
}
}
}
그리고 Index 메서드에서 뷰를 추가했듯이 동일하게 뷰를 추가해줍니다.
Create.cshtml 에서 Category모델을 기반으로 폼을 생성하고, <form> 태그의 POST 메소드로 새로운 카테고리를 추가하는 기능을 만들어 줍니다.
@model Category
<form method="post">
<div class="border p-3 mt-4">
<div class="row pb-2">
<h2 class="text-primary">Create Category</h2>
<hr />
</div>
<div class="mb-3">
<label asp-for="Name">Name</label>
<input asp-for="Name" class="form-control"/>
</div>
<div class="mb-3">
<label asp-for="DisplayOrder">DisplayOrder</label>
<input asp-for="DisplayOrder" class="form-control" />
</div>
<button type="submit" class="btn btn-primary" style="width:150px">Create</button>
<a asp-controller="Category" asp-action="Index" class="btn btn-secondary" style="width:150px">
Back to List
</a>
</div>
</form>
여기서 폼 안에 있는 요소들은 asp-for 속성을 사용하여 Category 모델의 속성과 연결됩니다. 예를 들어 asp-for="Name"은 Category Model의 Name 속성에 대한 입력 필드를 생성합니다. 입력 필드에 입력한 값은 Name 속성에 바인딩됩니다.
카테고리 생성 버튼을 누르면 POST 메서드를 사용하여 Create 액션으로 데이터를 전송합니다.
여기서 빠진게 HTTP POST 요청을 처리하는 액션 메서드가 빠져있습니다.
다시 CategoryController 로 돌아가서 POST 요청을 처리하는 메서드를 추가하도록 하겠습니다.
using BulkyBookWeb.Data;
using BulkyBookWeb.Models;
using Microsoft.AspNetCore.Mvc;
namespace BulkyBookWeb.Controllers
{
public class CategoryController : Controller
{
private readonly ApplicationDbContext _db;
public CategoryController(ApplicationDbContext db)
{
_db = db;
}
public IActionResult Index()
{
IEnumerable<Category> objCategoryList = _db.Categories.ToList();
return View(objCategoryList);
}
//GET
public IActionResult Create()
{
return View();
}
//POST
[HttpPost]
[ValidateAntiForgeryToken]
public IActionResult Create(Category obj)
{
_db.Categories.Add(obj);
_db.SaveChanges();
return RedirectToAction("Index");
}
}
}
여기서 [HttpPost] 액션 필터는 HTTP POST 메서드에만 응답하도록 설정됩니다.
[ValidateAntiForgeryToken] 액션 필터는 서버 측에서 생성한 토큰과 함께 폼 데이터를 제출하는 것을 요구합니다. 이 토큰은 클라이언트 측에서 제출된 폼 데이터와 함께 서버로 다시 전송되어, 서버 측에서는 이 토큰을 검증하여 CSRF 공격을 방지합니다.
Category obj는 뷰에서 입력된 카테고리 정보를 모델 바인딩하여 받아온 객체입니다.
_db.Categories.Add(obj) 코드는 받아온 카테고리 객체(obj)를 데이터베이스의 Categories 테이블에 추가합니다.
_db.SaveChanges()는 변경 사항을 데이터베이스에 저장하는 메서드입니다.
RedirectToAction("Index")는 Index 액션으로 리디렉션하여 Index 페이지로 이동합니다.
추가적으로,
해당 페이지를 Index에서 들어갈 수 있게 Index.cshtml 에서 아래의 버튼을 추가해 줍니다.
<a asp-controller="Category" asp-action="Create" class="btn btn-primary">
Create New Category
</a>
Create New Category 버튼을 클릭하면, Category 컨트롤러의 Create 액션 메서드(GET)로 이동합니다.
이제 모두 잘 작동되나 싶지만 한 가지 문제가 있습니다.
데이터를 생성하는데 Name 이나 DisplayOrder 부분에 입력하지 않고 생성하게 되면 오류가 발생합니다.
그러므로 데이터가 입력되어 있지 않았을 경우의 예외처리가 필요합니다.
닷넷에세 제공되는 태그 헬퍼 기능 중에 asp-validation-for="” 기능을 사용합니다.
asp-validation-for는 사용자가 유효하지 않은 값을 입력하면 ModelState 오류가 발생하는데, 이때 오류 메시지를 사용자에게 표시해주는 기능입니다.
아래처럼 추가해줍니다.
@model Category
<form method="post">
<div class="border p-3 mt-4">
<div class="row pb-2">
<h2 class="text-primary">Create Category</h2>
<hr />
</div>
<div class="mb-3">
<label asp-for="Name">Name</label>
<input asp-for="Name" class="form-control"/>
<span asp-validation-for="Name" class="text-danger"></span>
</div>
<div class="mb-3">
<label asp-for="DisplayOrder">DisplayOrder</label>
<input asp-for="DisplayOrder" class="form-control" />
<span asp-validation-for="DisplayOrder" class="text-danger"></span>
</div>
<button type="submit" class="btn btn-primary" style="width:150px">Create</button>
<a asp-controller="Category" asp-action="Index" class="btn btn-secondary" style="width:150px">
Back to List
</a>
</div>
</form>
마지막으로 서버 사이드에서의 예외처리도 추가하겠습니다.
카테고리 컨트롤러로 돌아와서 “ModelState.IsValid” 를 활용해서 서버 사이드에서의 예외처리도 추가해줍니다.
ModelState.IsValid는 .NET MVC 프레임워크에서 사용되는 개체 유효성 검사 도구 중 하나로 모델 상태를 검증하고, 모델에 대한 바인딩, 유효성 검사 및 모델 상태 오류를 관리해줍니다.
using BulkyBookWeb.Data;
using BulkyBookWeb.Models;
using Microsoft.AspNetCore.Mvc;
namespace BulkyBookWeb.Controllers
{
public class CategoryController : Controller
{
private readonly ApplicationDbContext _db;
public CategoryController(ApplicationDbContext db)
{
_db = db;
}
public IActionResult Index()
{
IEnumerable<Category> objCategoryList = _db.Categories.ToList();
return View(objCategoryList);
}
//GET
public IActionResult Create()
{
return View();
}
//POST
[HttpPost]
[ValidateAntiForgeryToken]
public IActionResult Create(Category obj)
{
if (ModelState.IsValid) // Server Side 예외처리
{
_db.Categories.Add(obj);
_db.SaveChanges();
return RedirectToAction("Index");
}
return View(obj);
}
}
}
이제 정상적으로 모두 잘 작동됩니다.
'.NET > CRUD' 카테고리의 다른 글
[.NET] 컨트롤러와 뷰(View) 구현하기 (0) | 2023.03.18 |
---|---|
[.NET] 데이터베이스 마이그레이션 하기 (0) | 2023.03.11 |
[.NET] 데이터베이스 연결(DbContext 클래스) (0) | 2023.03.10 |