메모
이 자습서의 업데이트된 버전은 최신 버전의 Visual Studio를 사용하여 여기에서 사용할 수 있습니다. 새 자습서에서는 ASP.NET Core MVC를 사용하여 이 자습서를 통해 많은 개선 사항을 제공합니다.
이 자습서에서는 컨트롤러 및 뷰를 사용하여 ASP.NET Core MVC에 대해 설명합니다. Razor Pages는 웹 UI 빌드를 더 쉽고 생산성 있게 만드는 페이지 기반 프로그래밍 모델인 ASP.NET Core의 새로운 대안입니다. MVC 버전 전에 Razor Pages 자습서를 사용하는 것이 좋습니다. Razor Pages 자습서:
- 따라하기 쉽습니다.
- 더 많은 기능을 다룹니다.
- 새 앱 개발을 위한 기본 접근 방식입니다.
검색 방법 및 검색 보기 추가
이 섹션에서는 장르 또는 이름으로 영화를 검색할 Index 수 있는 검색 기능을 작업 메서드에 추가합니다.
사전 요구 사항
이 섹션의 스크린샷과 일치하려면 애플리케이션(F5)을 실행하고 데이터베이스에 다음 동영상을 추가해야 합니다.
| Title | 출시 날짜 | 장르 | 가격 |
|---|---|---|---|
| 고스트버스터즈 | 6/8/1984 | 코미디 | 6.99 |
| 고스트버스터즈 II | 6/16/1989 | 코미디 | 6.99 |
| 유인원의 행성 | 3/27/1986 | 조치 | 5.99 |
인덱스 양식 업데이트
먼저 작업 메서드를 Index 기존 클래스로 업데이트합니다 MoviesController . 코드는 다음과 같습니다.
public ActionResult Index(string searchString)
{
var movies = from m in db.Movies
select m;
if (!String.IsNullOrEmpty(searchString))
{
movies = movies.Where(s => s.Title.Contains(searchString));
}
return View(movies);
}
메서드의 Index 첫 번째 줄은 다음 LINQ 쿼리를 만들어 영화를 선택합니다.
var movies = from m in db.Movies
select m;
쿼리는 이 시점에서 정의되지만 데이터베이스에 대해 아직 실행되지 않았습니다.
매개 변수에 searchString 문자열이 포함된 경우 영화 쿼리는 다음 코드를 사용하여 검색 문자열 값을 필터링하도록 수정됩니다.
if (!String.IsNullOrEmpty(searchString))
{
movies = movies.Where(s => s.Title.Contains(searchString));
}
위의 s => s.Title 코드는 람다 식입니다. 람다는 위의 코드에서 사용되는 Where 메서드와 같은 표준 쿼리 연산자 메서드에 대한 인수로 메서드 기반 LINQ 쿼리에서 사용됩니다. LINQ 쿼리는 정의될 때 또는 메서드를 호출 WhereOrderBy하여 수정할 때 실행되지 않습니다. 대신 쿼리 실행이 지연됩니다. 즉, 실현된 값이 실제로 반복되거나 ToList 메서드가 호출될 때까지 식의 평가가 지연됩니다. 샘플에서 Search 쿼리는 Index.cshtml 보기에서 실행됩니다. 지연된 쿼리 실행에 대한 자세한 내용은 쿼리 실행을 참조하세요.
이제 Index 보기를 업데이트하여 사용자에게 양식을 표시할 수 있습니다.
애플리케이션을 실행하고 /Movies/Index로 이동합니다. 쿼리 문자열(예: ?searchString=ghost)을 URL에 추가합니다. 필터링된 동영상이 표시됩니다.
메서드의 Index 시그니처를 매개 변수로 idid 변경하면 매개 변수가 {id} 파일에 설정된 기본 경로의 자리 표시자와 일치 합니다.
{controller}/{action}/{id}
원래 Index 메서드는 다음과 같습니다.
public ActionResult Index(string searchString)
{
var movies = from m in db.Movies
select m;
if (!String.IsNullOrEmpty(searchString))
{
movies = movies.Where(s => s.Title.Contains(searchString));
}
return View(movies);
}
수정된 Index 메서드는 다음과 같습니다.
public ActionResult Index(string id)
{
string searchString = id;
var movies = from m in db.Movies
select m;
if (!String.IsNullOrEmpty(searchString))
{
movies = movies.Where(s => s.Title.Contains(searchString));
}
return View(movies);
}
이제 쿼리 문자열 값 대신 경로 데이터(URL 세그먼트)로 검색 제목을 전달할 수 있습니다.
그러나 사용자가 영화를 검색하려고 할 때마다 URL을 수정하지는 않습니다. 이제 영화를 필터링하는 데 도움이 되는 UI를 추가합니다. 경로 바인딩 ID 매개 변수를 전달하는 방법을 테스트하기 위해 메서드의 Index 서명을 변경한 경우 메서드가 Index 다음과 같은 searchString문자열 매개 변수를 사용하도록 다시 변경합니다.
public ActionResult Index(string searchString)
{
var movies = from m in db.Movies
select m;
if (!String.IsNullOrEmpty(searchString))
{
movies = movies.Where(s => s.Title.Contains(searchString));
}
return View(movies);
}
Views\Movies\Index.cshtml 파일을 열고 바로 뒤 @Html.ActionLink("Create New", "Create")아래에 강조 표시된 양식 태그를 추가합니다.
@model IEnumerable<MvcMovie.Models.Movie>
@{
ViewBag.Title = "Index";
}
<h2>Index</h2>
<p>
@Html.ActionLink("Create New", "Create")
@using (Html.BeginForm()){
<p> Title: @Html.TextBox("SearchString") <br />
<input type="submit" value="Filter" /></p>
}
</p>
도우미가 Html.BeginForm 열려 있는 <form> 태그를 만듭니다. 사용자가 Html.BeginForm 버튼을 클릭하여 양식을 제출할 때, 이 도우미는 양식이 자기 자신에게 전송되도록 합니다.
Visual Studio 2013은 보기 파일을 표시하고 편집할 때 개선된 기능이 있습니다. 보기 파일이 열려 있는 애플리케이션을 실행하면 Visual Studio 2013에서 올바른 컨트롤러 작업 메서드를 호출하여 보기를 표시합니다.
위의 이미지와 같이 Visual Studio에서 인덱스 보기가 열려 있는 상태에서 Ctr F5 또는 F5를 탭하여 애플리케이션을 실행한 다음 동영상을 검색해 봅니다.
HttpPost 메서드는 Index 오버로드가 없습니다. 메서드가 애플리케이션의 상태를 변경하지 않고 데이터를 필터링하기 때문에 필요하지 않습니다.
다음 HttpPost Index 메서드를 추가할 수 있습니다. 이 경우 액션 호출자는 HttpPost Index 메서드와 일치하며, HttpPost Index 메서드는 아래 그림과 같이 실행됩니다.
[HttpPost]
public string Index(FormCollection fc, string searchString)
{
return "<h3> From [HttpPost]Index: " + searchString + "</h3>";
}
그러나 이 HttpPost 버전의 Index 메서드를 추가하는 경우에도 이를 모두 구현하는 방법은 제한됩니다. 특정 검색을 책갈피로 설정하거나 동일하게 필터링된 영화 목록을 보기 위해 클릭할 수 있는 링크를 친구에게 보내려고 한다고 가정합니다. HTTP POST 요청의 URL은 GET 요청(localhost:xxxxx/Movies/Index)의 URL과 동일합니다. URL 자체에는 검색 정보가 없습니다. 현재 검색 문자열 정보는 양식 필드 값으로 서버에 전송됩니다. 이것은 즉, 그 검색 정보를 URL로 즐겨찾기에 추가하거나 친구에게 보낼 수 없다는 것을 의미합니다.
해결책은 URL에 검색 정보를 추가하고 Index 메서드의 HttpGet 버전으로 라우팅되도록 지정하는 POST 요청의 오버로드 BeginForm를 사용하는 것입니다. 기존 매개 변수 없는 BeginForm 메서드를 다음 태그로 바꿉다.
@using (Html.BeginForm("Index","Movies",FormMethod.Get))
이제 검색을 제출할 때 URL에 검색 쿼리 문자열이 포함됩니다.
HttpGet Index 메서드가 존재하더라도 검색은 HttpPost Index 작업 메서드로 이동합니다.
장르별 검색 추가
HttpPost 메서드의 Index 버전을 추가한 경우, 지금 삭제하십시오.
다음으로 사용자가 장르별로 영화를 검색할 수 있도록 하는 기능을 추가합니다.
Index 메서드를 다음 코드로 바꿉니다.
public ActionResult Index(string movieGenre, string searchString)
{
var GenreLst = new List<string>();
var GenreQry = from d in db.Movies
orderby d.Genre
select d.Genre;
GenreLst.AddRange(GenreQry.Distinct());
ViewBag.movieGenre = new SelectList(GenreLst);
var movies = from m in db.Movies
select m;
if (!String.IsNullOrEmpty(searchString))
{
movies = movies.Where(s => s.Title.Contains(searchString));
}
if (!string.IsNullOrEmpty(movieGenre))
{
movies = movies.Where(x => x.Genre == movieGenre);
}
return View(movies);
}
이 버전의 Index 메서드는, 즉 movieGenre이라는 추가 매개 변수를 사용합니다. 처음 몇 줄의 코드는 데이터베이스에서 영화 장르를 저장할 개체를 만듭니 List 다.
다음 코드는 데이터베이스에서 모든 장르를 검색하는 LINQ 쿼리입니다.
var GenreQry = from d in db.Movies
orderby d.Genre
select d.Genre;
이 코드는 제네릭 AddRange 컬렉션의 메서드를 사용하여 List 목록에 모든 고유 장르를 추가합니다. (한정자가 없으면 Distinct 중복된 장르가 추가됩니다. 예를 들어 샘플에서 코미디가 두 번 추가됩니다). 그런 다음, 코드는 개체에 ViewBag.MovieGenre 장르 목록을 저장합니다. 범주 데이터(예: 영화 장르)를 SelectList 개체 ViewBag로 저장한 다음 드롭다운 목록 상자에서 범주 데이터에 액세스하는 것이 MVC 애플리케이션의 일반적인 방법입니다.
다음 코드는 매개 변수를 확인하는 movieGenre 방법을 보여줍니다. 비어 있지 않은 경우 코드는 영화 쿼리를 추가로 제한하여 선택한 영화를 지정된 장르로 제한합니다.
if (!string.IsNullOrEmpty(movieGenre))
{
movies = movies.Where(x => x.Genre == movieGenre);
}
앞에서 설명한 대로 Index 쿼리는 작업 메서드가 반환되고 View에서 영화 목록이 순회될 때까지 데이터베이스에서 실행되지 않습니다.
장르별 검색을 지원하기 위해 인덱스 보기에 태그 추가
Views\Movies\Index.cshtml 파일에 Html.DropDownList 도우미를 TextBox 도우미 바로 앞에 추가합니다. 완료된 마크업은 다음과 같습니다.
@model IEnumerable<MvcMovie.Models.Movie>
@{
ViewBag.Title = "Index";
}
<h2>Index</h2>
<p>
@Html.ActionLink("Create New", "Create")
@using (Html.BeginForm("Index", "Movies", FormMethod.Get))
{
<p>
Genre: @Html.DropDownList("movieGenre", "All")
Title: @Html.TextBox("SearchString")
<input type="submit" value="Filter" />
</p>
}
</p>
<table class="table">
다음 코드에서:
@Html.DropDownList("movieGenre", "All")
"MovieGenre" 매개변수는 DropDownList 도우미가 ViewBag에서 IEnumerable<SelectListItem>을 찾을 수 있도록 하는 키를 제공합니다.
ViewBag은 작업 메서드에서 채워졌습니다.
public ActionResult Index(string movieGenre, string searchString)
{
var GenreLst = new List<string>();
var GenreQry = from d in db.Movies
orderby d.Genre
select d.Genre;
GenreLst.AddRange(GenreQry.Distinct());
ViewBag.movieGenre = new SelectList(GenreLst);
var movies = from m in db.Movies
select m;
if (!String.IsNullOrEmpty(searchString))
{
movies = movies.Where(s => s.Title.Contains(searchString));
}
if (!string.IsNullOrEmpty(movieGenre))
{
movies = movies.Where(x => x.Genre == movieGenre);
}
return View(movies);
}
"All" 매개 변수는 옵션 레이블을 제공합니다. 브라우저에서 해당 선택을 검사하면 해당 "값" 특성이 비어 있음을 알 수 있습니다. 컨트롤러는 문자열을 필터링할 뿐 if 그 문자열을 null 하거나 비우지 않으므로, movieGenre 빈 값을 제출하면 모든 장르가 표시됩니다.
기본적으로 선택할 옵션을 설정할 수도 있습니다. 기본 옵션으로 "Comedy"를 원하는 경우 다음과 같이 컨트롤러의 코드를 변경합니다.
ViewBag.movieGenre = new SelectList(GenreLst, "Comedy");
애플리케이션을 실행하고 /Movies/Index로 탐색합니다. 장르, 영화 이름 및 두 기준별로 검색을 시도합니다.
이 섹션에서는 사용자가 영화 제목 및 장르별로 검색할 수 있도록 하는 검색 작업 방법 및 보기를 만들었습니다. 다음 섹션에서는 모델에 속성을 추가하는 방법과 테스트 데이터베이스를 Movie 자동으로 만드는 이니셜라이저를 추가하는 방법을 살펴보겠습니다.