파트 10: ASP.NET Core MVC - Details 메서드 및 Delete 메서드 살펴보기
- 본 번역문서의 원문은 Examining the Details and Delete methods docs.asp.net 입니다.
- 본 번역문서는 ASP.NET Core MVC : Details 메서드 및 Delete 메서드 살펴보기 www.taeyo.net 에서도 함께 제공됩니다.
먼저 Movie
컨트롤러를 열고 Details
메서드부터 살펴보겠습니다:
// GET: Movies/Details/5
public async Task<IActionResult> Details(int? id)
{
if (id == null)
{
return NotFound();
}
var movie = await _context.Movie.SingleOrDefaultAsync(m => m.ID == id);
if (movie == null)
{
return NotFound();
}
return View(movie);
}
이 액션 메서드의 주석에는 MVC 스캐폴딩 엔진이 코드를 생성하면서 메서드를 호출할 수 있는 한 가지 HTTP 요청 사례를 기입해 놓았습니다.
Movies
컨트롤러와 Details
메서드, 그리고 id
값, 이렇게 세 가지 URL 세그먼트들로 구성된 GET 요청이 그것입니다.
대부분 기억하시겠지만 이 세그먼트들은 Startup.cs 파일에서 설정됩니다.
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});
Code First를 사용하면 SingleOrDefaultAsync
메서드를 통해서 손쉽게 원하는 데이터를 검색할 수 있습니다.
Details 메서드에 보안과 관련해서 구현된 주목할 만한 특징 한 가지는, 영화 정보를 이용해서 무언가 작업을 수행하기 전에 항상 먼저 검색 메서드의 결과가 존재하는지 여부부터 확인한다는 점입니다.
만약 이 검사를 수행하지 않으면, 악의적인 사용자가 목록 페이지의 링크를 통해서 얻을 수 있는 URL인 http://localhost:xxxx/Movies/Details/1 을 http://localhost:xxxx/Movies/Details/12345 같은 URL로 변조해서 (즉, 실제로 존재하지 않는 유효하지 않은 영화 정보를 지정해서) 사이트에 오류를 만들어낼 수 있습니다.
따라서 영화 정보가 null인지 확인하지 않는다면 응용 프로그램이 예외를 던질 것입니다.
계속해서 이번에는 Delete
메서드와 DeleteConfirmed
메서드를 살펴봅니다.
// GET: Movies/Delete/5
public async Task<IActionResult> Delete(int? id)
{
if (id == null)
{
return NotFound();
}
var movie = await _context.Movie.SingleOrDefaultAsync(m => m.ID == id);
if (movie == null)
{
return NotFound();
}
return View(movie);
}
// POST: Movies/Delete/5
[HttpPost, ActionName("Delete")]
[ValidateAntiForgeryToken]
public async Task<IActionResult> DeleteConfirmed(int id)
{
var movie = await _context.Movie.SingleOrDefaultAsync(m => m.ID == id);
_context.Movie.Remove(movie);
await _context.SaveChangesAsync();
return RedirectToAction("Index");
}
이 코드의 HTTP GET Delete
메서드는 지정된 영화 정보를 삭제하는 것이 아니라, 단지 삭제 작업(HttpPost)을 승인할 수 있는 영화 정보 뷰를 반환할 뿐이라는 점에 주의하시기 바랍니다.
GET 요청의 응답으로 삭제 작업을 수행하면 (또는 수정 작업이나 생성 작업을 비롯한 데이터 변경이 발생하는 모든 유형의 작업을 수행하면) 보안상의 취약점이 발생합니다.
그리고 데이터를 삭제하는 [HttpPost]
메서드의 이름이 DeleteConfirmed
로 지정되어 있는 것을 볼 수 있는데, 이는 HTTP POST 메서드에 고유한 시그니처 및 이름을 부여하기 위한 것입니다.
두 메서드의 시그니처를 비교해보면 다음과 같습니다:
// GET: Movies/Delete/5
public async Task<IActionResult> Delete(int? id)
// POST: Movies/Delete/
[HttpPost, ActionName("Delete")]
[ValidateAntiForgeryToken]
public async Task<IActionResult> DeleteConfirmed(int id)
공통 언어 런타임(CLR, Common Language Runtime)에서 오버로드 된 메서드의 시그니처는 유일해야합니다 (즉, 메서드의 이름이 같을 수는 있지만 매개변수들의 목록은 달라야 합니다).
그러나 현재 상황은 두 가지 Delete
메서드(GET 버전과 POST 버전)가 모두 필요한 경우임에 반해, 공교롭게도 두 메서드의 매개변수 시그니처가 동일합니다.
(즉, 두 메서드 모두 하나의 정수형 매개변수를 받습니다.)
이 문제점을 해결할 수 있는 방법은 두 가지가 있습니다.
첫 번째 방법은 두 메서드의 이름을 서로 다르게 지정하는 것입니다.
본문의 예제에서 스캐폴딩 메커니즘 역시 이 방식을 따르고 있음을 확인할 수 있습니다.
그러나 여전히 사소한 문제점이 존재하는데, ASP.NET이 URL의 세그먼트들을 액션 메서드와 매핑할 때 메서드의 이름을 기준으로 처리하기 때문에, 지금처럼 메서드 이름을 변경해버리면 라우팅이 적절한 액션 메서드를 찾을 수 없게 됩니다.
이 문제의 해결방법은 본문의 예제 코드에서 볼 수 있는 것처럼 ActionName("Delete")
어트리뷰트를 DeleteConfirmed
메서드에 지정하는 것입니다.
이 어트리뷰트를 적용하면 /Delete/ 세그먼트가 포함된 URL에 대한 POST 요청을 라우팅 시스템을 통해서 DeleteConfirmed
메서드로 원활하게 매핑할 수 있습니다.
또는 동일한 이름과 시그니처를 갖고 있는 메서드의 문제점을 해결할 수 있는 또 다른 일반적인 방법은 아예 POST 메서드의 시그니처에 인위적으로 사용하지 않는 추가적인 매개변수를 추가하는 것입니다.
검색 기능 추가하기 파트에서 notUsed
매개변수를 추가했던 이유가 바로 이 때문으로, [HttpPost] Delete
메서드도 동일한 방식으로 처리할 수 있습니다:
[ValidateAntiForgeryToken]
public async Task<IActionResult> Delete(int id, bool notUsed)
{
var movie = await _context.Movie.SingleOrDefaultAsync(m => m.ID == id);
_context.Movie.Remove(movie);
await _context.SaveChangesAsync();
return RedirectToAction("Index");
}
- 파트 1: ASP.NET Core MVC - 시작하기 2016-05-28 08:00
- 파트 2: ASP.NET Core MVC - 컨트롤러 추가하기 2016-06-02 08:00
- 파트 3: ASP.NET Core MVC - 뷰 추가하기 2016-06-06 08:00
- 파트 4: ASP.NET Core MVC - 모델 추가하기 2016-06-13 08:00
- 파트 5: ASP.NET Core MVC - SQL Server LocalDB로 작업하기 2016-06-17 08:00
- 파트 6: ASP.NET Core MVC - 컨트롤러 메서드와 뷰 살펴보기 2016-06-24 08:00
- 파트 7: ASP.NET Core MVC - 검색 기능 추가하기 2016-07-01 08:00
- 파트 8: ASP.NET Core MVC - 새로운 필드 추가하기 2016-07-08 08:00
- 파트 9: ASP.NET Core MVC - 유효성 검사 추가하기 2016-07-11 08:00
- 파트 10: ASP.NET Core MVC - Details 메서드 및 Delete 메서드 살펴보기 2016-07-15 08:00