이 자습서에서는 입력 양식을 만드는 방법과 ASP.NET 웹 페이지(Razor)을 사용할 때 사용자의 입력을 처리하는 방법에 대한 기본 사항을 보여 줍니다. 이제 데이터베이스가 있으므로 양식 기술을 사용하여 사용자가 데이터베이스에서 특정 영화를 찾을 수 있습니다. ASP.NET 웹 페이지 사용하여 데이터 표시 소개를 통해 시리즈를 완료한 것으로 가정합니다.
학습할 내용:
- 표준 HTML 요소를 사용하여 양식을 만드는 방법입니다.
- 양식에서 사용자의 입력을 읽는 방법입니다.
- 사용자가 제공하는 검색어를 사용하여 데이터를 선택적으로 가져오는 SQL 쿼리를 만드는 방법입니다.
- 페이지에 사용자가 입력한 내용을 "기억"하는 필드가 있는 방법입니다.
설명된 기능/기술:
Request
개체- SQL
Where
절입니다.
만들 내용
이전 자습서에서는 데이터베이스를 만들고, 데이터베이스에 데이터를 추가한 다음, 도우미를 WebGrid
사용하여 데이터를 표시했습니다. 이 자습서에서는 특정 장르의 영화를 찾거나 제목에 입력한 단어가 포함된 검색 상자를 추가합니다. (예를 들어 장르가 "Action"이거나 제목에 "Harry" 또는 "Adventure"가 포함된 모든 영화를 찾을 수 있습니다.)
이 자습서를 완료하면 다음과 같은 페이지가 표시됩니다.
페이지의 목록 부분은 마지막 자습서인 그리드와 동일합니다. 차이점은 그리드에 검색한 영화만 표시된다는 것입니다.
HTML Forms 정보
(HTML 양식을 만든 경험이 있고 와 POST
의 차이점 GET
이 있는 경우 이 섹션을 건너뛸 수 있습니다.)
양식에는 텍스트 상자, 단추, 라디오 단추, 검사 상자, 드롭다운 목록 등 사용자 입력 요소가 있습니다. 사용자는 이러한 컨트롤을 채우거나 선택한 다음 단추를 클릭하여 양식을 제출합니다.
양식의 기본 HTML 구문은 다음 예제에서 설명합니다.
<form method="post">
<input type="text" name="name" value="" />
<br/>
<input type="submit" name="submit" value="Submit" />
</form>
이 태그는 페이지에서 실행되면 다음 그림과 같은 간단한 양식을 만듭니다.
요소는 <form>
제출할 HTML 요소를 묶습니다. (쉬운 실수는 페이지에 요소를 추가한 다음 요소 내에 배치하는 것을 잊어버리는 <form>
것입니다. 이 경우 아무것도 제출되지 않습니다.) 특성은 method
브라우저에 사용자 입력을 제출하는 방법을 알려줍니다. 서버에서 업데이트를 수행하는 경우 또는 get
서버에서 데이터를 가져오는 경우 로 설정합니다post
.
팁
GET, POST 및 HTTP 동사 안전
브라우저와 서버가 정보를 교환하는 데 사용하는 프로토콜인 HTTP는 기본 작업에서 매우 간단합니다. 브라우저는 몇 개의 동사만 사용하여 서버에 요청합니다. 웹용 코드를 작성할 때 이러한 동사와 브라우저 및 서버에서 사용하는 방식을 이해하는 것이 유용합니다. 가장 일반적으로 사용되는 동사는 다음과 같습니다.
-
GET
. 브라우저는 이 동사를 사용하여 서버에서 무언가를 가져옵니다. 예를 들어 브라우저에 URL을 입력하면 브라우저에서 원하는 페이지를 요청하는 작업을 수행합니다GET
. 페이지에 그래픽이 포함된 경우 브라우저는 추가GET
작업을 수행하여 이미지를 가져옵니다.GET
작업이 서버에 정보를 전달해야 하는 경우 정보는 쿼리 문자열의 URL의 일부로 전달됩니다. -
POST
. 브라우저는 서버에서 추가 또는 변경될 데이터를 제출하기 위해 요청을 보냅니POST
다. 예를 들어 동사는POST
데이터베이스에서 레코드를 만들거나 기존 레코드를 변경하는 데 사용됩니다. 대부분의 경우 양식을 작성하고 제출 단추를 클릭하면 브라우저에서 작업을 수행합니다POST
.POST
작업에서 서버에 전달되는 데이터는 페이지 본문에 있습니다.
이러한 동 GET
사 간의 중요한 차이점은 작업이 서버에서 어떤 것도 변경하지 않아야 한다는 것입니다. 또는 좀 더 추상적인 방식으로 GET
작업을 수행해도 서버의 상태가 변경되지는 않습니다. 원하는 만큼 동일한 리소스에 대해 작업을 여러 번 수행할 GET
수 있으며 해당 리소스는 변경되지 않습니다.
GET
(작업은 종종 "안전"하거나 기술 용어를 사용하는 것이 idempotent라고 합니다.) 반면 요청은 POST
작업을 수행할 때마다 서버에서 무언가를 변경합니다.
두 가지 예제는 이러한 차이점을 설명하는 데 도움이 됩니다. Bing 또는 Google과 같은 엔진을 사용하여 검색을 수행하는 경우 하나의 텍스트 상자로 구성된 양식을 입력한 다음 검색 단추를 클릭합니다. 브라우저는 URL의 GET
일부로 전달된 상자에 입력한 값을 사용하여 작업을 수행합니다. 검색 작업이 서버의 리소스를 GET
변경하지 않고 정보를 가져오기 때문에 이러한 형식의 폼에 작업을 사용하는 것은 괜찮습니다.
이제 온라인으로 주문하는 프로세스를 고려합니다. 주문 세부 정보를 입력한 다음 제출 단추를 클릭합니다. 이 작업은 새 주문 레코드, 계정 정보 변경 및 기타 많은 변경 내용과 같은 서버의 변경이 발생하므로 요청이 됩니다 POST
. 작업과 GET
달리 요청을 반복 POST
할 수 없습니다. 요청을 다시 제출할 때마다 서버에서 새 주문을 생성합니다. (이와 같은 경우 웹 사이트는 제출 단추를 두 번 이상 클릭하지 않도록 경고하거나 실수로 양식을 다시 제출하지 않도록 제출 단추를 사용하지 않도록 설정합니다.)
이 자습서에서는 작업과 POST
작업을 모두 GET
사용하여 HTML 양식으로 작업합니다. 각 경우에 사용하는 동사가 적절한 이유를 설명합니다.
HTTP 동사에 대한 자세한 내용은 W3C 사이트의 메서드 정의 문서를 참조하세요.
대부분의 사용자 입력 요소는 HTML <input>
요소입니다.
형식이 원하는 사용자 입력 컨트롤의 종류를 나타내는 위치와 같습니다<input type="type" name="name">,
. 이러한 요소는 일반적인 요소입니다.
- 텍스트 상자:
<input type="text">
- 확인란:
<input type="check">
- 라디오 단추:
<input type="radio">
- 단추:
<input type="button">
- 제출 단추:
<input type="submit">
요소를 사용하여 <textarea>
여러 줄 텍스트 상자와 <select>
요소를 만들어 드롭다운 목록 또는 스크롤 가능한 목록을 만들 수도 있습니다. HTML 양식 요소에 대한 자세한 내용은 W3Schools 사이트의 HTML 양식 및 입력 을 참조하세요.
특성은 name
매우 중요합니다. 이름은 나중에 요소의 값을 가져오는 방법이기 때문에 곧 표시됩니다.
흥미로운 부분은 페이지 개발자가 사용자의 입력으로 수행하는 작업입니다. 이러한 요소와 연결된 기본 제공 동작은 없습니다. 대신 사용자가 입력하거나 선택한 값을 가져와서 작업을 수행해야 합니다. 이 자습서에서 알아봅니다.
팁
HTML5 및 입력 양식
알고 있듯이 HTML은 전환 중이며 최신 버전(HTML5)에는 사용자가 정보를 입력하는 보다 직관적인 방법에 대한 지원이 포함되어 있습니다. 예를 들어 HTML5에서 사용자(페이지 개발자)는 사용자가 날짜를 입력하도록 페이지에 알릴 수 있습니다. 그러면 브라우저에서 사용자가 수동으로 날짜를 입력하도록 요구하지 않고 자동으로 일정을 표시할 수 있습니다. 그러나 HTML5는 새로운 기능이며 아직 모든 브라우저에서 지원되지 않습니다.
ASP.NET 웹 페이지 사용자의 브라우저가 수행하는 범위까지 HTML5 입력을 지원합니다. HTML5의 요소에 대한 새 특성에 대한 <input>
아이디어는 W3Schools 사이트의 HTML <입력> 형식 특성을 참조하세요.
폼 만들기
WebMatrix의 파일 작업 영역에서 Movies.cshtml 페이지를 엽니다.
닫 </h1>
는 태그 다음에 호출의 여 <div>
는 grid.GetHtml
태그 앞에 다음 태그를 추가합니다.
<form method="get">
<div>
<label for="searchGenre">Genre to look for:</label>
<input type="text" name="searchGenre" value="" />
<input type="Submit" value="Search Genre" /><br/>
(Leave blank to list all movies.)<br/>
</div>
</form>
이 태그는 라는 searchGenre
텍스트 상자와 제출 단추가 있는 양식을 만듭니다. 텍스트 상자 및 제출 단추는 특성이 로 <form>
설정된 요소 method
로 get
묶입니다. (텍스트 상자를 배치하고 요소 내에 <form>
단추를 제출하지 않으면 단추를 클릭할 때 아무 것도 제출되지 않습니다.) 여기서 동사를 사용하는 GET
이유는 서버에서 변경하지 않는 폼을 만들기 때문입니다. 이는 검색 결과일 뿐입니다. (이전 자습서에서는 서버에 변경 내용을 제출하는 방법인 메서드를 사용 post
했습니다. 이 내용은 다음 자습서에서 다시 확인할 수 있습니다.)
페이지를 실행합니다. 폼에 대한 동작을 정의하지는 않았지만 양식의 모양을 확인할 수 있습니다.
텍스트 상자에 "코미디"와 같은 값을 입력합니다. 그런 다음 검색 장르를 클릭합니다.
페이지의 URL을 기록해 둡니다. 요소의 method
특성을 get
로 설정 <form>
했으므로 입력한 값은 이제 다음과 같이 URL의 쿼리 문자열에 속합니다.
http://localhost:45661/Movies.cshtml?searchGenre=Comedy
양식 값 읽기
페이지에는 데이터베이스 데이터를 가져오고 결과를 표에 표시하는 일부 코드가 이미 포함되어 있습니다. 이제 검색어를 포함하는 SQL 쿼리를 실행할 수 있도록 텍스트 상자의 값을 읽는 일부 코드를 추가해야 합니다.
폼의 메서드를 get
로 설정했기 때문에 다음과 같은 코드를 사용하여 텍스트 상자에 입력한 값을 읽을 수 있습니다.
var searchTerm = Request.QueryString["searchGenre"];
Request.QueryString
개체(QueryString
개체의 Request
속성)에는 작업의 일부로 제출된 요소의 값이 GET
포함됩니다. 속성에는 Request.QueryString
양식에 제출된 값의 컬렉션 (목록)이 포함됩니다. 개별 값을 얻으려면 원하는 요소의 이름을 지정합니다. 따라서 텍스트 상자를 만드는 요소(searchTerm
)에 <input>
특성이 있어야 name
합니다. (개체에 Request
대한 자세한 내용은 나중에 사이드바 를 참조하세요.)
텍스트 상자의 값을 읽을 수 있을 만큼 간단합니다. 그러나 사용자가 텍스트 상자에 아무 것도 입력하지 않았지만 검색을 클릭한 경우 검색할 항목이 없으므로 해당 클릭을 무시할 수 있습니다.
다음 코드는 이러한 조건을 구현하는 방법을 보여 주는 예제입니다. (이 코드를 아직 추가할 필요가 없습니다. 잠시 후에 추가합니다.)
if(!Request.QueryString["searchGenre"].IsEmpty() ) {
// Do something here
}
테스트는 다음과 같은 방식으로 세분화됩니다.
- 의 값
Request.QueryString["searchGenre"]
, 즉 라는searchGenre
요소에<input>
입력된 값을 가져옵니다. - 메서드를 사용하여 비어 있는지 확인합니다
IsEmpty
. 이 메서드는 폼 요소와 같은 항목에 값이 포함되어 있는지 여부를 확인하는 표준 방법입니다. 그러나 정말, 당신은 비어 있지 않은 경우에만 걱정, 따라서 ... -
!
테스트 앞에 연산자를 추가합니다IsEmpty
. 연산자는!
논리적 NOT을 의미합니다.
일반 영어로 전체 if
조건은 다음으로 변환됩니다. 양식의 searchGenre 요소가 비어 있지 않으면 ...
이 블록은 검색어를 사용하는 쿼리를 만드는 단계를 설정합니다. 다음 섹션에서 구성을 완료합니다.
팁
Request 개체
개체에는 Request
페이지가 요청되거나 제출될 때 브라우저가 애플리케이션에 보내는 모든 정보가 포함됩니다. 이 개체에는 사용자가 제공하는 모든 정보(예: 텍스트 상자 값 또는 업로드할 파일)가 포함됩니다. 또한 쿠키, URL 쿼리 문자열의 값(있는 경우), 실행 중인 페이지의 파일 경로, 사용자가 사용하는 브라우저 유형, 브라우저에 설정된 언어 목록 등과 같은 모든 종류의 추가 정보도 포함됩니다.
개체는 Request
값의 컬렉션 (목록)입니다. 이름을 지정하여 컬렉션에서 개별 값을 가져옵니다.
var someValue = Request["name"];
개체는 Request
실제로 여러 하위 집합을 노출합니다. 예:
-
Request.Form
는 요청이 요청POST
인 경우 제출된<form>
요소 내의 요소에서 값을 제공합니다. -
Request.QueryString
는 URL의 쿼리 문자열에 있는 값만 제공합니다. (와 같은http://mysite/myapp/page?searchGenre=action&page=2
?searchGenre=action&page=2
URL에서 URL의 섹션은 쿼리 문자열입니다.) -
Request.Cookies
컬렉션을 사용하면 브라우저에서 보낸 쿠키에 액세스할 수 있습니다.
제출된 양식에 있는 것으로 알고 있는 값을 얻으려면 를 사용할 Request["name"]
수 있습니다. 또는 더 구체적인 버전 Request.Form["name"]
(요청의 경우 POST
) 또는 Request.QueryString["name"]
(요청의 경우)을 GET
사용할 수 있습니다. 물론 이름은 가져올 항목의 이름입니다.
가져올 항목의 이름은 사용 중인 컬렉션 내에서 고유해야 합니다. 이 때문에 개체는 Request
및 Request.QueryString
와 같은 Request.Form
하위 집합을 제공합니다. 페이지에 라는 양식 요소가 있고 라는 userName
userName
쿠키도 포함되어 있다고 가정합니다. 를 가져오는 Request["userName"]
경우 양식 값 또는 쿠키를 원하는지 여부가 모호합니다. 그러나 또는 Request.Cookie["userName"]
를 가져오는 Request.Form["userName"]
경우 가져올 값에 대해 명시적입니다.
구체적이고 또는 Request.QueryString
와 같이 Request.Form
관심 있는 의 Request
하위 집합을 사용하는 것이 좋습니다. 이 자습서에서 만드는 간단한 페이지의 경우 실제로는 차이가 없습니다. 그러나 더 복잡한 페이지를 만들 때 명시적 버전을 Request.Form
사용하거나 Request.QueryString
페이지에 양식(또는 여러 양식), 쿠키, 쿼리 문자열 값 등이 포함될 때 발생할 수 있는 문제를 방지하는 데 도움이 될 수 있습니다.
검색어를 사용하여 쿼리 만들기
이제 사용자가 입력한 검색어를 가져오는 방법을 알게 되었으므로 이를 사용하는 쿼리를 만들 수 있습니다. 데이터베이스에서 모든 동영상 항목을 가져오기 위해 다음 문과 같은 SQL 쿼리를 사용합니다.
SELECT * FROM Movies
특정 영화만 얻으려면 절이 포함된 쿼리를 Where
사용해야 합니다. 이 절을 사용하면 쿼리에서 행이 반환되는 조건을 설정할 수 있습니다. 예를 들면 다음과 같습니다.
SELECT * FROM Movies WHERE Genre = 'Action'
기본 형식은 입니다 WHERE column = value
. 찾고 있는 항목에 =
따라 ,( >
보다 큼), (보다 작음), <
(같지 않음), <>
<=
(보다 작거나 같음) 등 외에 다른 연산자를 사용할 수 있습니다.
궁금한 경우 SQL 문은 대/소문자를 구분 SELECT
하지 않습니다. 는 (또는 select
)와 Select
동일합니다. 그러나 사람들은 읽기 쉽도록 및 와 WHERE
같은 SELECT
SQL 문에서 키워드를 대문자로 사용하는 경우가 많습니다.
검색어를 매개 변수로 전달
특정 장르를 검색하는 것은 충분히 쉽지만(WHERE Genre = 'Action'
) 사용자가 입력하는 장르를 검색할 수 있기를 원합니다. 이렇게 하려면 검색할 값에 대한 자리 표시자를 포함하는 SQL 쿼리로 만듭니다. 이 명령은 다음과 같습니다.
SELECT * FROM Movies WHERE Genre = @0
자리 표시자는 문자 뒤에 @
0이 잇는 문자입니다. 짐작할 수 있듯이 쿼리에는 여러 자리 표시자가 포함될 수 있으며 , , @1
, @2
등으로 이름이 지정@0
됩니다.
쿼리를 설정하고 실제로 값을 전달하려면 다음과 같은 코드를 사용합니다.
selectCommand = "SELECT * FROM Movies WHERE Genre = @0";
selectedData = db.Query(selectCommand, Request.QueryString["searchGenre"]);
이 코드는 그리드에 데이터를 표시하기 위해 이미 수행한 것과 비슷합니다. 차이점은 다음과 같습니다.
- 쿼리에는 자리 표시자(
WHERE Genre = @0"
)가 포함됩니다. - 쿼리는 변수(
selectCommand
)에 배치됩니다. 이전에는 쿼리를 메서드에db.Query
직접 전달했습니다. - 메서드를
db.Query
호출할 때 자리 표시자에 사용할 쿼리와 값을 모두 전달합니다. 쿼리에 여러 자리 표시자가 있는 경우 모두 별도의 값으로 메서드에 전달합니다.
이러한 모든 요소를 함께 배치하면 다음 코드가 표시됩니다.
if(!Request.QueryString["searchGenre"].IsEmpty() ) {
searchTerm = Request.QueryString["searchGenre"];
selectCommand = "SELECT * FROM Movies WHERE Genre = @0";
selectedData = db.Query(selectCommand, searchTerm);
}
참고
중요! 자리 표시자(예: @0
)를 사용하여 SQL 명령에 값을 전달하는 것은 보안을 위해 매우 중요 합니다. 변수 데이터에 대한 자리 표시자를 사용하여 여기에서 볼 수 있는 방법은 SQL 명령을 생성해야 하는 유일한 방법입니다.
사용자로부터 받은 리터럴 텍스트와 값을 함께 배치(연결)하여 SQL 문을 생성하지 마세요. 사용자 입력을 SQL 문에 연결하면 악의적인 사용자가 데이터베이스를 해킹하는 값을 페이지에 제출하는 SQL 삽입 공격에 사이트가 열립니다. (MSDN 웹 사이트 SQL 삽입 문서에서 자세히 확인할 수 있습니다.)
검색 코드를 사용하여 영화 페이지 업데이트
이제 Movies.cshtml 파일에서 코드를 업데이트할 수 있습니다. 시작하려면 페이지 맨 위에 있는 코드 블록의 코드를 다음 코드로 바꿉 있습니다.
var db = Database.Open("WebPagesMovies");
var selectCommand = "SELECT * FROM Movies";
var searchTerm = "";
여기서 차이점은 나중에 전달할 db.Query
변수에 쿼리를 selectCommand
배치했다는 것입니다. SQL 문을 변수에 배치하면 검색을 수행하기 위해 수행할 문을 변경할 수 있습니다.
이 두 줄도 제거했으며 나중에 다시 배치할 예정입니다.
var selectedData = db.Query("SELECT * FROM Movies");
var grid = new WebGrid(source: selectedData, rowsPerPage: 3);
쿼리를 아직 실행하지 않고(즉, 호출 db.Query
) 도우미를 아직 초기화 WebGrid
하지 않으려는 경우 실행해야 하는 SQL 문을 파악한 후에는 이러한 작업을 수행합니다.
이 다시 작성된 블록 후에 검색을 처리하기 위한 새 논리를 추가할 수 있습니다. 완료된 코드는 다음과 같습니다. 이 예제와 일치하게 페이지의 코드를 업데이트합니다.
@{
var db = Database.Open("WebPagesMovies") ;
var selectCommand = "SELECT * FROM Movies";
var searchTerm = "";
if(!Request.QueryString["searchGenre"].IsEmpty() ) {
selectCommand = "SELECT * FROM Movies WHERE Genre = @0";
searchTerm = Request.QueryString["searchGenre"];
}
var selectedData = db.Query(selectCommand, searchTerm);
var grid = new WebGrid(source: selectedData, defaultSort: "Genre", rowsPerPage:3);
}
이제 페이지가 다음과 같이 작동합니다. 페이지가 실행 될 때마다 코드는 데이터베이스 selectCommand
를 열고 변수는 테이블에서 모든 레코드를 가져오는 SQL 문으로 Movies
설정 됩니다. 또한 이 코드는 변수를 searchTerm
초기화합니다.
그러나 현재 요청에 요소 값이 searchGenre
포함된 경우 코드는 장르를 검색할 절을 포함하는 Where
쿼리로 설정 selectCommand
됩니다. 또한 검색 상자에 대해 전달된 항목(아무것도 아닐 수 있습니다)으로 설정합니다 searchTerm
.
에 있는 SQL 문에 selectCommand
관계없이 코드는 를 호출 db.Query
하여 쿼리를 실행하고 에 searchTerm
있는 모든 것을 전달합니다. 에 searchTerm
아무 것도 없는 경우 아무 것도 중요하지 않습니다. 이 경우 값을 selectCommand
전달할 매개 변수가 없기 때문입니다.
마지막으로 코드는 이전과 WebGrid
마찬가지로 쿼리 결과를 사용하여 도우미를 초기화합니다.
SQL 문과 검색어를 변수에 배치하면 코드에 유연성이 추가된 것을 볼 수 있습니다. 이 자습서의 뒷부분에서 볼 수 있듯이 이 기본 프레임워크를 사용하고 다양한 유형의 검색에 대한 논리를 계속 추가할 수 있습니다.
장르별 검색 기능 테스트
WebMatrix에서 Movies.cshtml 페이지를 실행합니다. 장르에 대한 텍스트 상자가 있는 페이지가 표시됩니다.
테스트 레코드 중 하나에 대해 입력한 장르를 입력한 다음 검색을 클릭합니다. 이번에는 해당 장르와 일치하는 영화 목록이 표시됩니다.
다른 장르를 입력하고 다시 검색합니다. 검색이 대/소문자를 구분하지 않는 것을 볼 수 있도록 모든 소문자 또는 모든 대문자를 사용하여 장르를 입력해 보세요.
사용자가 입력한 내용 "기억 중"
장르를 입력하고 검색 장르를 클릭한 후 해당 장르에 대한 목록을 보았습니다. 그러나 검색 텍스트 상자가 비어 있습니다. 즉, 입력한 내용이 기억나지 않습니다.
이 동작이 발생하는 이유를 이해하는 것이 중요합니다. 페이지를 제출하면 브라우저가 웹 서버에 요청을 보냅니다. ASP.NET 요청을 받으면 페이지의 새로운 instance 만들고 코드를 실행한 다음 페이지를 브라우저로 다시 렌더링합니다. 그러나 실제로 페이지는 이전 버전의 자체로 작업하고 있다는 것을 알지 못합니다. 알고 있는 것은 양식 데이터가 포함된 요청을 받았다는 것입니다.
처음으로 또는 제출하여 페이지를 요청할 때마다 새 페이지가 표시됩니다. 웹 서버에 마지막 요청의 메모리가 없습니다. 어느 쪽도 ASP.NET 않으며 브라우저도 수행하지 않습니다. 페이지의 이러한 개별 인스턴스 간의 유일한 연결은 해당 인스턴스 간에 전송하는 모든 데이터입니다. 예를 들어 페이지를 제출하는 경우 새 페이지 instance 이전 instance 보낸 양식 데이터를 가져올 수 있습니다. (페이지 간에 데이터를 전달하는 또 다른 방법은 쿠키를 사용하는 것입니다.)
이 상황을 설명하는 공식적인 방법은 웹 페이지가 상태 비정상이라고 말하는 것입니다. 웹 서버와 페이지 자체 및 페이지의 요소는 페이지의 이전 상태에 대한 정보를 유지 관리하지 않습니다. 개별 요청에 대한 상태를 유지 관리하면 초당 수천, 심지어 수십만 개의 요청을 처리하는 웹 서버의 리소스가 빠르게 소진되기 때문에 웹이 이러한 방식으로 설계되었습니다.
그래서 텍스트 상자가 비어 있었습니다. 페이지를 제출한 후 ASP.NET 페이지의 새 instance 만들고 코드 및 태그를 실행했습니다. 이 코드에는 ASP.NET 입력란에 값을 넣으라고 말한 것은 아무것도 없었습니다. 따라서 ASP.NET 아무 작업도 수행하지 않았고 텍스트 상자는 값 없이 렌더링되었습니다.
실제로 이 문제를 해결할 수 있는 쉬운 방법이 있습니다. 텍스트 상자에 입력한 장르 는 코드에서 사용할 수 있습니다. 이 장르는 에 있습니다 Request.QueryString["searchGenre"]
.
다음 예제와 같이 특성이 에서 값을 가져오도록 value
텍스트 상자의 searchTerm
태그를 업데이트합니다.
<input type="text" name="searchGenre" value="@Request.QueryString["searchGenre"]" />
이 페이지에서는 해당 변수에 입력한 value
장르도 포함되어 있으므로 특성을 searchTerm
변수로 설정할 수도 있습니다. 그러나 여기에 표시된 대로 개체를 value
사용하여 Request
특성을 설정하는 것이 이 작업을 수행하는 표준 방법입니다. (이 작업을 수행하려는 경우를 가정합니다. 경우에 따라 필드에 값 이 없는 페이지를 렌더링할 수 있습니다. 이 모든 것은 앱에서 어떤 일이 일어나고 있는지에 따라 달라집니다.)
참고
암호에 사용되는 텍스트 상자의 값을 "기억"할 수 없습니다. 사람들이 코드를 사용하여 암호 필드를 채울 수 있도록 하는 보안 구멍이 될 수 있습니다.
페이지를 다시 실행하고 장르를 입력한 다음 검색 장르를 클릭합니다. 이번에는 검색 결과가 표시될 뿐만 아니라 텍스트 상자에 마지막으로 입력한 내용이 기억됩니다.
타이틀에서 모든 Word 검색
이제 장르를 검색할 수 있지만 제목을 검색할 수도 있습니다. 검색할 때 제목을 정확히 얻기가 어렵기 때문에 제목 내의 아무 곳에나 나타나는 단어를 검색할 수 있습니다. SQL에서 이렇게 하려면 다음과 같은 연산자 및 구문을 사용합니다 LIKE
.
SELECT * FROM Movies WHERE Title LIKE '%adventure%'
이 명령은 제목에 "adventure"가 포함된 모든 영화를 가져옵니다. 연산자를 LIKE
사용하는 경우 와일드카드 문자를 %
검색 용어의 일부로 포함합니다. 검색 LIKE 'adventure%'
은 "'adventure'로 시작"을 의미합니다. 기술적으로는 "문자열 'adventure' 뒤에 무엇이든 옵니다."를 의미합니다. 마찬가지로 검색 용어 LIKE '%adventure'
는 "'adventure'라는 문자열이 뒤에 잇는 모든 항목"을 의미하며, 이는 "adventure"로 끝나는 또 다른 방법입니다.
따라서 검색 용어 LIKE '%adventure%'
는 "타이틀의 아무 곳이나 '모험'을 의미합니다." (기술적으로는 "타이틀의 모든 항목, '모험', 그 다음으로 무엇이든.")
요소 내에서 <form>
장르 검색의 닫는 </div>
태그 바로 아래에 다음 태그를 추가합니다(닫는 </form>
요소 바로 앞).
<div>
<label for="SearchTitle">Movie title contains the following:</label>
<input type="text" name="searchTitle" value="@Request.QueryString["searchTitle"]" />
<input type="Submit" value="Search Title" /><br/>
</div>
이 검색을 처리하는 코드는 검색을 어셈블해야 한다는 점을 제외하고 장르 검색의 코드와 LIKE
비슷합니다. 페이지 맨 위에 있는 코드 블록 안에 장르 검색을 위한 블록 바로 다음에 if
이 if
블록을 추가합니다.
if(!Request.QueryString["searchTitle"].IsEmpty() ) {
selectCommand = "SELECT * FROM Movies WHERE Title LIKE @0";
searchTerm = "%" + Request["searchTitle"] + "%";
}
이 코드는 검색에서 연산자를 사용하고 LIKE
코드가 검색 용어 전후에 "%
"를 배치한다는 점을 제외하고 앞에서 본 것과 동일한 논리를 사용합니다.
페이지에 다른 검색을 추가하는 것이 얼마나 쉬운지 확인합니다. 해야 할 일은 다음과 같습니다.
-
if
관련 검색 상자에 값이 있는지 여부를 확인하기 위해 테스트된 블록을 만듭니다. - 변수를
selectCommand
새 SQL 문으로 설정합니다. - 변수를
searchTerm
쿼리에 전달할 값으로 설정합니다.
다음은 타이틀 검색에 대한 새 논리를 포함하는 전체 코드 블록입니다.
@{
var db = Database.Open("WebPagesMovies") ;
var selectCommand = "SELECT * FROM Movies";
var searchTerm = "";
if(!Request.QueryString["searchGenre"].IsEmpty() ) {
selectCommand = "SELECT * FROM Movies WHERE Genre = @0";
searchTerm = Request.QueryString["searchGenre"];
}
if(!Request.QueryString["searchTitle"].IsEmpty() ) {
selectCommand = "SELECT * FROM Movies WHERE Title LIKE @0";
searchTerm = "%" + Request["searchTitle"] + "%";
}
var selectedData = db.Query(selectCommand, searchTerm);
var grid = new WebGrid(source: selectedData, defaultSort: "Genre", rowsPerPage:8);
}
이 코드에서 수행하는 기능을 요약하면 다음과 같습니다.
- 및 변수는
searchTerm
selectCommand
맨 위에서 초기화됩니다. 이러한 변수는 페이지에서 사용자가 수행하는 작업을 기반으로 적절한 검색어(있는 경우) 및 적절한 SQL 명령으로 설정합니다. 기본 검색은 데이터베이스에서 모든 영화를 가져오는 간단한 경우입니다. - 및 에 대한
searchGenre
테스트에서 코드는 검색할 값으로 설정합니다searchTerm
.searchTitle
또한 이러한 코드 블록은 해당 검색에 적합한 SQL 명령으로 설정selectCommand
됩니다. - 메서드는
db.Query
에 있는 SQL 명령과 에selectedCommand
있는 값을 사용하여 한 번만 호출됩니다searchTerm
. 검색어(장르 및 제목 단어 없음)가 없는 경우 값searchTerm
은 빈 문자열입니다. 그러나 이 경우 쿼리에 매개 변수가 필요하지 않기 때문에 중요하지 않습니다.
타이틀 검색 기능 테스트
이제 완료된 검색 페이지를 테스트할 수 있습니다. Movies.cshtml을 실행합니다.
장르를 입력하고 검색 장르를 클릭합니다. 그리드는 이전과 같이 해당 장르의 영화를 표시합니다.
제목 단어를 입력하고 제목 검색을 클릭합니다. 표에는 제목에 해당 단어가 있는 영화가 표시됩니다.
두 텍스트 상자를 모두 비워 두고 두 단추 중 하나를 클릭합니다. 그리드는 모든 영화를 표시합니다.
쿼리 결합
수행할 수 있는 검색은 배타적일 수 있습니다. 두 검색 상자에 값이 있더라도 제목과 장르를 동시에 검색할 수 없습니다. 예를 들어 제목에 "Adventure"가 포함된 모든 액션 영화를 검색할 수는 없습니다. 페이지가 지금 코딩되므로 장르와 타이틀에 대한 값을 입력하면 타이틀 검색이 우선적으로 적용됩니다. 조건을 결합하는 검색을 만들려면 다음과 같은 구문이 있는 SQL 쿼리를 만들어야 합니다.
SELECT * FROM Movies WHERE Genre = @0 AND Title LIKE @1
그리고 다음과 같은 문을 사용하여 쿼리를 실행해야 합니다(대략 말).
var selectedData = db.Query(selectCommand, searchGenre, searchTitle);
검색 조건의 많은 순열을 허용하는 논리를 만들면 볼 수 있듯이 약간 관련될 수 있습니다. 따라서 여기서 중지합니다.
다음 출시 예정
다음 자습서에서는 사용자가 데이터베이스에 영화를 추가할 수 있도록 양식을 사용하는 페이지를 만듭니다.
동영상 페이지에 대한 전체 목록(검색으로 업데이트됨)
@{
var db = Database.Open("WebPagesMovies") ;
var selectCommand = "SELECT * FROM Movies";
var searchTerm = "";
if(!Request.QueryString["searchGenre"].IsEmpty() ) {
selectCommand = "SELECT * FROM Movies WHERE Genre = @0";
searchTerm = Request.QueryString["searchGenre"];
}
if(!Request.QueryString["searchTitle"].IsEmpty() ) {
selectCommand = "SELECT * FROM Movies WHERE Title LIKE @0";
searchTerm = "%" + Request["searchTitle"] + "%";
}
var selectedData = db.Query(selectCommand, searchTerm);
var grid = new WebGrid(source: selectedData, defaultSort: "Genre", rowsPerPage:3);
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Movies</title>
<style type="text/css">
.grid { margin: 4px; border-collapse: collapse; width: 600px; }
.grid th, .grid td { border: 1px solid #C0C0C0; padding: 5px; }
.head { background-color: #E8E8E8; font-weight: bold; color: #FFF; }
.alt { background-color: #E8E8E8; color: #000; }
</style>
</head>
<body>
<h1>Movies</h1>
<form method="get">
<div>
<label for="searchGenre">Genre to look for:</label>
<input type="text" name="searchGenre" value="@Request.QueryString["searchGenre"]" />
<input type="Submit" value="Search Genre" /><br/>
(Leave blank to list all movies.)<br/>
</div>
<div>
<label for="SearchTitle">Movie title contains the following:</label>
<input type="text" name="searchTitle" value="@Request.QueryString["searchTitle"]" />
<input type="Submit" value="Search Title" /><br/>
</div>
</form>
<div>
@grid.GetHtml(
tableStyle: "grid",
headerStyle: "head",
alternatingRowStyle: "alt",
columns: grid.Columns(
grid.Column("Title"),
grid.Column("Genre"),
grid.Column("Year")
)
)
</div>
</body>
</html>
추가 리소스
- Razor 구문을 사용하는 ASP.NET 웹 프로그래밍 소개
- W3Schools 사이트의 SQL WHERE 절
- W3C 사이트의 메서드 정의 문서