파트 9: Details 메서드 및 Delete 메서드 살펴보기

등록일시: 2012-07-03 11:07,  수정일시: 2016-09-02 09:06
조회수: 4,136
이 문서는 ASP.NET MVC 기술을 널리 알리고자 하는 개인적인 취지로 제공되는 번역문서입니다. 이 문서에 대한 모든 저작권은 마이크로소프트에 있으며 요청이 있을 경우 언제라도 게시가 중단될 수 있습니다. 번역 내용에 오역이 존재할 수 있고 주석은 번역자 개인의 의견일 뿐이며 마이크로소프트는 이에 관한 어떠한 보장도 하지 않습니다. 번역이 완료된 이후에도 대상 제품 및 기술이 개선되거나 변경됨에 따라 원문의 내용도 변경되거나 보완되었을 수 있으므로 주의하시기 바랍니다.

이번에는 자동으로 생성된 Details 메서드와 Delete 메서드를 조금 더 자세히 살펴보도록 하겠습니다.

Details 메서드 및 Delete 메서드 살펴보기

다시 Movie 컨트롤러를 열고, Details 메서드를 살펴보십시요.

public ActionResult Details(int id = 0)
{
    Movie movie = db.Movies.Find(id);
    if (movie == null)
    {
        return HttpNotFound();
    }
    return View(movie);
}

이와 같이 Code First를 사용하면 Find 메서드를 이용해서 손쉽게 데이터를 검색할 수 있습니다. 그리고, 보안과 관련하여 Details 메서드에 구현된 중요한 기능 한 가지는, 검색된 영화 정보를 이용해서 작업을 수행하기 전에, 항상 코드에서 Find 메서드의 검색 결과가 존재하는지부터 먼저 확인한다는 점입니다. 만약, 이 검사를 수행하지 않는다면, 악의적인 사용자가 링크에 의해서 만들어진 URL인 http://localhost:xxxx/Movies/Details/1http://localhost:xxxx/Movies/Details/12345 등의 URL로 변경해서 (실제로 존재하지 않는 아무 영화 정보나 지정해서) 사이트로부터 오류를 이끌어낼 수도 있습니다. 그런 경우, 검색된 영화 정보가 null인지 확인하지 않는다면, 데이터베이스 오류가 발생할 것이기 때문입니다.

그러면, 이번에는 Delete 메서드와 DeleteConfirmed 메서드를 살펴보겠습니다.

// GET: /Movies/Delete/5

public ActionResult Delete(int id = 0)
{
    Movie movie = db.Movies.Find(id);
    if (movie == null)
    {
        return HttpNotFound();
    }
    return View(movie);
}

//
// POST: /Movies/Delete/5

[HttpPost, ActionName("Delete")]
public ActionResult DeleteConfirmed(int id = 0)
{
    Movie movie = db.Movies.Find(id);
    if (movie == null)
    {
        return HttpNotFound();
    }
    db.Movies.Remove(movie);
    db.SaveChanges();
    return RedirectToAction("Index");
}

이 코드에서 HTTP Get Delete 메서드는 지정된 영화 정보를 실제로 삭제하는 것이 아니라, 단지 영화 정보를 제출해서 (HttpPost) 삭제 작업을 수행할 수 있는 뷰를 반환할 뿐이라는 점에 주의하시기 바랍니다. 그 이유는 삭제 작업을 (또는, 수정 작업이나, 생성 작업을 비롯한 데이터 변경이 발생하는 모든 작업을) GET 요청에서 수행하면 보안상 취약점이 발생하기 때문입니다. 이 문제점에 대한 보다 자세한 정보는 Stephen Walther의 블로그 포스트인 ASP.NET MVC Tip #46 — Don't use Delete Links because they create Security Holes를 참고하시기 바랍니다.

그리고, 실제로 데이터를 삭제하는 HttpPost 메서드에는 HTTP POST 메서드에 고유한 시그니처 혹은 이름을 부여하기 위해서 DeleteConfirmed라는 이름이 지정되어 있는 것을 볼 수 있습니다. 이 두 메서드의 시그니처를 비교해보면 다음과 같습니다:

// GET: /Movies/Delete/5
public ActionResult Delete(int id = 0)
 
//
// POST: /Movies/Delete/5
[HttpPost, ActionName("Delete")]
public ActionResult DeleteConfirmed(int id = 0)

공통 언어 런타임(CLR, Common Language Runtime)에서 오버로드 된 메서드들은 시그니처가 유일해야만 합니다 (즉, 메서드 이름은 같을 수가 있지만, 매개변수의 목록은 달라야 합니다). 그런데, 이 예제의 경우, 두 개의 Delete 메서드(GET 버전과 POST 버전)가 필요한 상황인데 반해, 공교롭게도 필요한 두 메서드의 시그니처가 동일합니다. (두 메서드 모두 하나의 정수형 매개변수를 받습니다.)

이 문제를 해결하려면 몇 가지 작업이 필요합니다. 우선 두 메서드의 이름이 서로 달라야 합니다. 이 예제에서 스캐폴딩 메커니즘 역시 같은 방식을 따르고 있는 것을 확인할 수 있습니다. 그러나, 아직도 문제가 남아 있는데, ASP.NET이 URL을 액션 메서드와 맵핑할 때, 메서드 이름을 기준으로 처리하므로, 지금처럼 메서드 이름을 변경하면, 라우팅이 적절한 액션 메서드를 찾을 수가 없게 됩니다. 이 문제의 해결방법은, 위의 코드에서도 알 수 있는 것처럼, 바로 DeleteConfirmed 메서드에 지정되어 있는 ActionName("Delete") 어트리뷰트를 지정하는 것입니다. 이 어트리뷰트를 이용하면 /Delete/가 포함된 URL에 대한 POST 요청도 라우팅 시스템을 통해서 DeleteConfirmed 메서드로 원활하게 맵핑시킬 수 있습니다.

동일한 이름 및 시그니처로 인한 문제점을 해결할 수 있는 또 다른 보편적인 방법은, 아예 인위적으로 사용하지 않는 매개변수를 POST 메서드의 시그니처에 추가하는 것입니다. 예를 들어서, 어떤 개발자들은 다음 코드처럼 POST 메서드에 전달되는 FormCollection 형식의 매개변수를 추가한 다음, 그냥 이 매개변수를 무시해버립니다.

public ActionResult Delete(FormCollection fcNotUsed, int id = 0)
{
    Movie movie = db.Movies.Find(id);
    if (movie == null)
    {
        return HttpNotFound();
    }
    db.Movies.Remove(movie);
    db.SaveChanges();
    return RedirectToAction("Index");
}

마무리

이제 여러분은 SQL 서버 컴팩트 데이터베이스에 데이터를 저장하는 완벽한 ASP.NET 응용 프로그램을 갖게 되었습니다. 영화 정보를 생성하고, 읽고, 변경하고, 삭제할 수 있으며 검색도 가능합니다.

기초적인 본 자습서에서는 먼저 컨트롤러를 구현한 다음, 이 컨트롤러와 뷰를 연결하고, 하드코딩 된 데이터를 뷰에 전달해봤습니다. 그리고, 데이터 모델을 설계 및 생성하고, Entity Framework Code First를 사용해서 해당 데이타 모델로부터 실시간으로 데이터베이스를 생성한 다음, ASP.NET MVC 스캐폴딩 시스템을 이용해서 기초적인 CRUD 작업들을 위한 액션 메서드와 뷰들을 자동적으로 생성했습니다. 그런 다음, 검색 폼을 추가해서 사용자들이 데이터베이스를 검색할 수 있도록 만들었습니다. 새로운 데이터 컬럼을 추가하기 위해서 데이터베이스를 변경했으며, 그 데이터를 생성하고 출력하기 위해서 두 개의 페이지도 수정했습니다. 그리고, 데이터 모델에 DataAnnotations 네임스페이스의 어트리뷰트들을 적용해서 유효성 검사를 추가했으며, 그 결과 클라이언트와 서버 양쪽에서 유효성 검사가 수행되었습니다.

만약, 이 응용 프로그램을 배포해보고 싶다면, 먼저 로컬 IIS 7 서버에서 테스트를 해보는 것이 좋습니다. 웹 플랫폼 인스톨러 링크를 이용하면 ASP.NET 응용 프로그램을 위한 IIS 설정을 활성화시킬 수 있습니다. 그리고, 다음의 배포 관련 문서들도 살펴보시기 바랍니다:

MSDN의 ASP.NET 관련 기사들을 살펴보시려면 계속해서 중급 수준의 자습서인 Creating an Entity Framework Data Model for an ASP.NET MVC ApplicationMVC Music Store를 살펴보는 것이 좋습니다. 그리고, http://asp.net/mvc에서 제공되는 다양한 동영상과 자료들도 살펴보시기 바랍니다. ASP.NET MVC 포럼에 질문을 올리시는 것도 좋은 방법입니다.

그러면, 즐거운 시간이 되시기 바랍니다!

- Rick Anderson blogs.msdn.com/rickAndy