파트 5: 컨트롤러에서 모델의 데이터에 접근하기

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

이번 강좌에서는 새로운 MoviesController 클래스를 생성하고, 뷰 템플릿을 이용해서 가져온 영화 데이터를 브라우저에 출력하는 코드를 작성해보도록 하겠습니다. 그러나, 다음 과정을 진행하기 전에 먼저 응용 프로그램부터 빌드하시기 바랍니다.

다른 컨트롤러를 만들 때처럼, Controllers 폴더를 마우스 오른쪽 버튼으로 클릭하고, Add > Controller를 선택해서 새로운 MoviesController 컨트롤러를 생성합니다. 방금 설명했던 것처럼, 응용 프로그램을 빌드해야만 본문의 지시와 동일한 옵션을 선택할 수 있습니다. 다음은 대화 상자에서 선택해야 할 옵션들입니다:

  • 컨트롤러 이름(Controller name): MoviesController.
  • 템플릿(Template): Controller with read/write actions and views, using Entity Framework.
  • 모델 클래스(Model class): Movie (MvcMovie.Models).
  • 데이터 컨텍스트 클래스(Data context class): MovieDBContext (MvcMovie.Models).
  • 뷰(Views): Razor (CSHTML). (기본값)

AddScaffoldedMovieController

대화 상자의 옵션을 모두 지정한 다음, Add를 클릭하면, Visual Studio Express가 다음의 폴더와 파일들을 생성해줍니다:

  • 프로젝트의 Controllers 폴더에 MoviesController.cs 파일이 생성됩니다.
  • 프로젝트의 Views 폴더에 Movies 폴더가 생성됩니다.
  • 새로운 Views\Movies 폴더에 Create.cshtml, Delete.cshtml, Details.cshtml, Edit.cshtml, Index.cshtml 파일이 생성됩니다.

NewMovieControllerScreenShot

바로 ASP.NET MVC 4가 여러분을 대신해서 자동으로 CRUD(Create, Read, Update, Delete)와 관련된 액션 메서드와 뷰들을 생성해주는 것입니다. (이런 방식으로 자동으로 만들어진 CRUD 액션 메서드와 뷰들을 다른 말로 스캐폴딩(Scaffolding)이라고도 부릅니다.) 결과적으로 별다른 노력 없이, 영화 정보를 생성, 조회, 수정, 삭제할 수 있는 완벽한 기능의 웹 응용 프로그램을 갖게 된 것입니다.

응용 프로그램을 다시 실행한 다음, 브라우저 주소 표시줄의 URL에 /Movies를 추가해서 Movies 컨트롤러로 이동해보십시요. 이 응용 프로그램은 기본 라우팅에 따라 동작하므로 (기본 라우팅은 Global.asax 파일에 정의되어 있습니다), 브라우저가 보낸 http://localhost:xxxxx/Movies에 대한 요청은 Movies 컨트롤러의 Index 액션 메서드로 라우트됩니다. 결국, http://localhost:xxxxx/Movies에 대한 요청과 http://localhost:xxxxx/Movies/Index에 대한 요청은 사실상 동일한 요청인 셈입니다. 현재는 데이터베이스에 저장된 영화 정보가 전혀 없으므로, 결과 페이지에는 다음과 같이 빈 영화 목록만 나타날 것입니다.

영화 정보 생성하기

목록 페이지에서 Create New 링크를 클릭한 다음, 적당한 영화 정보를 입력하고 Create 버튼을 클릭합니다.

그러면, 폼에 입력된 영화 정보가 서버로 제출되고, 이 정보는 다시 데이터베이스에 저장됩니다. 그런 다음, 새로 생성된 영화 정보 목록을 확인할 수 있는 /Movies URL로 다시 재전송됩니다.

IndexWhenHarryMet

테스트를 위해서 영화 정보를 몇 개 정도 더 생성해보십시요. 그리고, Edit, Details, Delete 링크를 사용해서 모든 기능들을 테스트해보시기 바랍니다.

생성된 코드 살펴보기

이제 브라우저를 닫고 Controllers\MoviesController.cs 파일을 열어서, 만들어져 있는 Index 메서드의 코드를 살펴보겠습니다. 이 컨트롤러의 Index 메서드 부분의 코드는 다음과 같습니다.

public class MoviesController : Controller 
{
    private MovieDBContext db = new MovieDBContext(); 

    //
    // GET: /Movies/ 

    public ActionResult Index() 
    {
        return View(db.Movies.ToList());
    }

이 코드의 다음 라인은, 이전 강좌에서 설명했던 영화 데이터베이스 컨텍스트의 인스턴스를 생성합니다. 이 영화 데이터베이스 컨텍스트를 사용해서 영화 정보를 질의하고, 수정하고, 삭제할 수 있습니다.

private MovieDBContext db = new MovieDBContext();

브라우저에서 Movies 컨트롤러를 요청하면 이 Index 메서드가 영화 데이터베이스의 Movies 테이블에 존재하는 모든 항목을 가져온 다음, 그 결과를 Index 뷰에 전달합니다.

강력한 형식의 모델과 @model 키워드

이전 강좌에서는 ViewBag 개체를 통해서 컨트롤러에서 뷰 템플릿으로 데이터나 개체를 전달하는 방법을 살펴봤습니다. ViewBag은 동적 개체로, 뷰에 정보를 전달할 때 편리한 후기 바인드(Late-Bound) 기능을 제공해줍니다.

그러나, ASP.NET MVC는 뷰 템플릿에 강력한 형식의 데이터나 개체를 전달할 수 있는 방법도 제공해줍니다. 이런 강력한 형식 기반의 접근방식은, 작성된 코드에 대한 보다 훌륭한 컴파일 시점 검사를 수행할 수 있게 해주고, Visual Studio Express 편집기에서 풍부한 인텔리센스의 이점를 제공해줍니다. Visual Studio Express 스캐폴딩 메커니즘은 MoviesController 클래스와 뷰 템플릿의 메서드 및 뷰를 생성할 때, 바로 이 접근방식을 사용합니다.

그러면 이번에는 Controllers\MoviesController.cs 파일에 만들어진 Details 메서드를 분석해보도록 하겠습니다. 다음 코드는 MoviesController 클래스의 Details 메서드 부분입니다. Movie 모델의 인스턴스가 Details 뷰로 전달되는 것을 확인할 수 있습니다.

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

이 메서드에서는 Movie 모델의 인스턴스를 Details 뷰로 전달하고 있습니다.

뷰 템플릿 파일의 상단에 @model 구문을 작성하면, 컨트롤러에서 뷰로 전달되기를 바라는 개체의 형식을 지정할 수 있습니다. Visual Studio Express는 MoviesController 클래스를 생성할 때, Details.cshtml 파일의 상단에 자동으로 다음과 같은 @model 구문을 추가해줍니다:

@model MvcMovie.Models.Movie

이렇게 뷰 상단에 @model 지시자를 작성하면, 강력한 형식인 Model 개체를 통해서 컨트롤러로부터 전달된 영화 정보에 접근할 수 있습니다. 가령, Details.cshtml 뷰 템플릿의 코드에서는 강력한 형식의 Model 개체를 이용해서, 각각의 영화 정보 필드를 DisplayNameFor 도우미 메서드와 DisplayFor 도우미 메서드에 전달합니다. 뿐만 아니라, Create 메서드와 Edit 메서드, 그리고 관련 뷰 템플릿들도 영화 모델 개체를 전달하고 전달받습니다.

계속해서 Index.cshtml 뷰 템플릿과 MoviesController.cs 파일의 Index 메서드를 다시 살펴보도록 하겠습니다. Index 액션 메서드에서 View 도우미 메서드를 호출할 때, List 개체를 생성하는 방식을 주의 깊게 살펴보시기 바랍니다. 생성된 Movies 목록은 컨트롤러에서 뷰로 전달됩니다:

public ActionResult Index()
{
    return View(db.Movies.ToList());
}

Visual Studio Express는 MoviesController 클래스를 생성할 때, Index.cshtml 파일의 상단에 자동으로 다음과 같은 @model 구문을 추가해줍니다:

@model IEnumerable<MvcMovie.Models.Movie>

이렇게 뷰 상단에 @model 지시자를 작성하면, 강력한 형식인 Model 개체를 통해서 컨트롤러로부터 전달된 영화 정보 목록에 접근할 수 있습니다. 가령, Index.cshtml 템플릿의 코드에서는 foreach 구문을 이용해서 강력한 형식인 Model 개체의 영화 정보 목록에 대해 루프문을 수행합니다:

@foreach (var item in Model) {
    <tr>
        <td>
            @Html.DisplayFor(modelItem => item.Title)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.ReleaseDate)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.Genre)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.Price)
        </td>
        <th>
            @Html.DisplayFor(modelItem => item.Rating)
        </th>
        <td>
            @Html.ActionLink("Edit", "Edit", new { id=item.ID }) |
            @Html.ActionLink("Details", "Details", { id=item.ID }) |
            @Html.ActionLink("Delete", "Delete", { id=item.ID }) 
        </td>
    </tr>
}

이 코드의 Model 개체는 강력한 형식이므로 (IEnumerable<Movie> 개체), 루프문 내부의 item 개체는 Movie 형식입니다. 결과적으로, 다른 여러 가지 장점들과 함께, 컴파일 시점 검사와 코드 편집기 상에서의 완벽한 인텔리센스를 지원 받을 수 있습니다.

ModelIntellisene

SQL 서버 LocalDB를 이용하여 작업하기

Entity Framework Code First는 제공된 데이터베이스 연결 문자열에 지정된 Movies 데이터베이스가 존재하지 않으면, 자동으로 해당 데이터베이스를 생성해줍니다. App_Data 폴더를 살펴보면 생성된 데이터베이스를 확인할 수 있습니다. 만약, Movies.sdf 파일이 보이지 않는다면, Solution Explorer의 툴바에서 Show All Files 버튼을 클릭한 다음, Refresh 버튼을 클릭하고, App_Data 폴더를 확장해보십시요.

SDF_in_SolnExp

그런 다음, Movies.mdf 파일을 마우스로 더블 클릭해서 DATABASE EXPLORER를 엽니다. 그리고, Tables 폴더를 확장해서 데이터베이스에 생성된 테이블들을 확인해봅니다.

DB_explorer

모두 두 개의 테이블이 존재하는 것을 볼 수 있는데, Movie 엔티티 모음이 저장되는 테이블과 EdmMetadata 테이블이 바로 그것입니다. EdmMetadata 테이블은 모델과 데이터베이스 간에 동기화가 필요한지 여부를 파악하기 위한 용도로 Entity Framework가 사용하는 테이블입니다.

두 테이블 중에서, Movies 테이블을 마우스 오른쪽 버튼으로 클릭한 다음, Show Table Data를 선택하면 여러분이 생성한 데이터를 확인할 수 있습니다.

그리고, 다시 Movies 테이블을 마우스 오른쪽 버튼으로 클릭한 다음, Open Table Definition을 선택하면 Entity Framework Code First가 자동으로 생성해준 테이블 구조를 살펴볼 수 있습니다.

MoviesTable

TableSchemaSM

앞에서 작성했던 Movie 클래스와 Movies 테이블의 스키마가 어떻게 서로 맵핑되는지 주의해서 살펴보시기 바랍니다. Entity Framework Code First는 Movie 클래스를 기반으로 이 스키마를 자동 생성합니다.

작업을 모두 마쳤으면, Movies.mdf 파일을 마우스 오른쪽 버튼으로 클릭한 다음, Close Connection을 클릭하여 연결을 닫습니다. (연결을 닫지 않으면, 다음 번에 프로젝트를 실행할 때 오류가 발생할 수도 있습니다.)

CloseConnection

이제 데이터베이스와 그 데이터베이스로부터 가져온 데이터를 출력해주는 간단한 목록 페이지가 만들어졌습니다. 그러면 계속해서 나머지 스캐폴딩 코드들을 살펴보고, 데이터베이스에서 영화를 검색할 수 있는 기능을 제공해주는 SearchIndex 메서드와 SearchIndex 뷰를 작성해보도록 하겠습니다.