Знакомство с веб-страницами ASP.NET — основы формы HTML

Tom FitzMacken

В этом руководстве показано, как создать входную форму и как обрабатывать входные данные пользователя при использовании веб-страниц ASP.NET (Razor). Теперь, когда у вас есть база данных, вы будете использовать навыки формы, чтобы пользователи нашли определенные фильмы в базе данных. Предполагается, что вы завершили серию, начав с Введения в отображение данных с использованием веб-страниц ASP.NET.

Что вы узнаете:

  • Создание формы с помощью стандартных HTML-элементов.
  • Как прочитать входные данные пользователя в форме.
  • Как создать SQL-запрос, который выборочно получает данные с помощью поискового термина, предоставляемого пользователем.
  • Как сделать так, чтобы поля на странице запоминали, что вводит пользователь.

Рассматриваются функции и технологии:

  • Объект Request.
  • Предложение Where в SQL.

Что вы будете создавать

В предыдущем руководстве вы создали базу данных, добавили в нее данные, а затем использовали вспомогательный WebGrid компонент для отображения данных. В этом руководстве вы добавите поле поиска, которое позволяет найти фильмы определенного жанра или название которого содержит любое слово, которое вы вводите. (Например, вы сможете найти все фильмы, жанр которых — "Действие" или название которого содержит "Гарри" или "Приключение".

Когда вы закончите работу с этим руководством, у вас будет страница, похожая на эту:

Страница

Часть списка страницы совпадает с последней частью руководства — сеткой. Разница будет в том, что сетка будет отображать только фильмы, которые вы искали.

Сведения о HTML-формах

(Если у вас есть опыт создания форм HTML и разницы между GET и POST, можно пропустить этот раздел.)

Форма содержит элементы ввода пользователей — текстовые поля, кнопки, переключатели, флажки, раскрывающийся список и т. д. Пользователи заполняют эти элементы управления или делают выбор, а затем отправляют форму, нажав кнопку.

Базовый синтаксис HTML формы показан в следующем примере:

<form method="post">
  <input type="text" name="name" value="" />
  <br/>
  <input type="submit" name="submit" value="Submit" />
</form>

При выполнении этой разметки на странице создается простая форма, которая выглядит следующим образом:

Базовая HTML-форма, отображаемая в браузере

Элемент <form> заключает элементы HTML для отправки. (Простая ошибка заключается в добавлении элементов на страницу, но затем забыть поместить их в <form> элемент. В этом случае ничего не отправляется.) Атрибут method сообщает браузеру, как отправить входные данные пользователя. Вы задаете это как post, если вы выполняете обновление на сервере, или как get, если вы просто извлекаете данные с сервера.

Подсказка

БЕЗОПАСНОСТЬ КОМАНД GET, POST и HTTP

ПРОТОКОЛ HTTP, используемый браузерами и серверами для обмена информацией, является удивительно простым в его основных операциях. Браузеры используют только несколько команд для выполнения запросов к серверам. При написании кода в Интернете полезно понять эти команды и как браузер и сервер используют их. Безусловно, наиболее часто используемые глаголы это:

  • GET. В браузере используется эта команда для получения чего-то с сервера. Например, при вводе URL-адреса в браузере, он выполняет GET операцию, чтобы запросить нужную страницу. Если страница содержит графику, браузер выполняет дополнительные GET операции для получения изображений. GET Если операция должна передать сведения на сервер, данные передаются как часть URL-адреса в строке запроса.
  • POST. Браузер отправляет POST запрос для отправки данных, которые будут добавлены или изменены на сервере. Например, POST команда используется для создания записей в базе данных или изменения существующих. Большую часть времени при заполнении формы и нажатии кнопки отправки браузер выполняет POST операцию. POST В операции данные, передаваемые серверу, находятся в теле страницы.

Важное различие между этими командами заключается в том, что GET операция не должна изменять что-либо на сервере или немного более абстрактно, GET операция не приводит к изменению состояния на сервере. Вы можете выполнять GET операцию с теми же ресурсами столько раз, сколько вам нравится, и эти ресурсы не изменяются. (Операция GET, часто называется "безопасной", или, используя технический термин, является идемпотентной.) В отличие от этого, само собой разумеется, POST запрос изменяет что-то на сервере каждый раз при выполнении операции.

Два примера помогут проиллюстрировать это различие. При выполнении поиска с помощью подсистемы Bing или Google вы заполняете форму, состоящую из одного текстового поля, а затем нажмите кнопку поиска. Браузер выполняет GET операцию, при этом значение, введенное в поле, передается как часть URL-адреса. GET Использование операции для этого типа формы вполне допустимо, так как операция поиска не изменяет никакие ресурсы на сервере, а просто извлекает информацию.

Теперь рассмотрим процесс заказа что-то в Интернете. Заполните сведения о заказе и нажмите кнопку "Отправить". Эта операция будет запросом POST , так как операция приведет к изменениям на сервере, таким как новая запись заказа, изменение сведений о вашей учетной записи и, возможно, многие другие изменения. GET В отличие от операции, вы не можете повторить POST запрос — если бы вы это сделали, каждый раз, когда вы повторно отправляете запрос, вы создаете новый заказ на сервере. (В таких случаях веб-сайты часто предупреждают вас не нажимать кнопку отправки более одного раза или отключать кнопку отправки, чтобы вы не повторите форму случайно.)

В рамках этого руководства вы будете использовать как GET операцию, так и POST операцию для работы с 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 см. в HTML Формы и Ввод на сайте W3Schools.)

Атрибут name очень важен, потому что именно через имя вы сможете получить значение элемента позже, как вы увидите в ближайшее время.

Интересная часть заключается в том, что вы, разработчик страницы, делаете с входными данными пользователя. Нет встроенного поведения, связанного с этими элементами. Вместо этого необходимо получить значения, введенные пользователем или выбранные пользователем, и сделать что-то с ними. Это то, что вы узнаете в этом руководстве.

Подсказка

HTML5 и входные формы

Как вы можете знать, HTML находится в переходе, и последняя версия (HTML5) включает поддержку более интуитивно понятных способов ввода информации пользователями. Например, в HTML5 вы (разработчик страницы) можете задать на странице, чтобы пользователь ввел дату. Затем браузер может автоматически отображать календарь, а не требовать, чтобы пользователь ввел дату вручную. Однако HTML5 является новым и пока не поддерживается во всех браузерах.

ASP.NET веб-страницы поддерживают элементы ввода HTML5 в той степени, в которой их поддерживает браузер пользователя. Для получения сведений о новых атрибутах элемента <input> в HTML5 см. раздел «Атрибут input< type> в HTML» на сайте W3Schools.

Создание формы

В 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 элемента <form> на get, введенное вами значение теперь является частью строки запроса в URL, как это:

http://localhost:45661/Movies.cshtml?searchGenre=Comedy

Чтение значений формы

Страница уже содержит код, который получает данные базы данных и отображает результаты в сетке. Теперь необходимо добавить код, который считывает значение текстового поля, чтобы можно было запустить SQL-запрос, содержащий термин поиска.

Так как для метода формы задано getзначение, можно прочитать значение, введенное в текстовое поле, с помощью следующего кода:

var searchTerm = Request.QueryString["searchGenre"];

Объект Request.QueryString (свойство QueryString объекта Request) включает значения элементов, отправленных в рамках операции GET. Свойство Request.QueryString содержит коллекцию (список) значений, отправленных в форме. Чтобы получить любое отдельное значение, укажите имя нужного элемента. Именно поэтому необходимо иметь name атрибут в элементе <input> (searchTerm), который создает текстовое поле. (Дополнительные сведения об объекте см. в Request панели позже.)

Это достаточно просто, чтобы прочитать значение текстового поля. Но если пользователь вообще ничего не ввел в текстовом поле, но щелкнул "Поиск " в любом случае, вы можете игнорировать этот щелчк, так как нет ничего для поиска.

В следующем примере кода показано, как реализовать эти условия. (Вам еще не нужно добавить этот код; вы сделаете это в данный момент.)

if(!Request.QueryString["searchGenre"].IsEmpty() ) {
     // Do something here
}

Тест структурирован следующим образом:

  • Получите значение Request.QueryString["searchGenre"], то есть значение, введённое в элемент <input> с именем searchGenre.
  • Узнайте, пустой ли он, с помощью метода IsEmpty. Этот метод является стандартным способом определить, содержит ли что-то (например, элемент формы) значение. Действительно, вас волнует только, если это не пусто, поэтому ...
  • Добавьте оператор ! перед тестом IsEmpty. (Оператор ! означает логическое НЕ).

На обычном английском языке все if условие преобразуется в следующее: если элемент searchGenre формы не пуст, то ...

Этот блок задает этап создания запроса, использующего поисковый термин. Вы сделаете это в следующем разделе.

Подсказка

Объект запроса

Объект Request содержит все сведения, которые браузер отправляет приложению при запросе или отправке страницы. Этот объект содержит любые сведения, которые предоставляет пользователь, например значения текстового поля или файл для отправки. Он также включает все дополнительные сведения, такие как файлы cookie, значения в строке запроса URL-адреса (если есть), путь к файлу запущенной страницы, тип браузера, используемый пользователем, список языков, заданных в браузере, и многое другое.

Объект Request представляет собой коллекцию (список) значений. Вы получаете отдельное значение из коллекции, указав его имя:

var someValue = Request["name"];

Объект Request фактически предоставляет несколько подмножеств. Рассмотрим пример.

  • Request.Form предоставляет значения из элементов внутри отправленного <form> элемента, если запрос является запросом POST .
  • Request.QueryString предоставляет только значения в строке запроса URL-адреса. (В URL-адресе, например http://mysite/myapp/page?searchGenre=action&page=2, ?searchGenre=action&page=2 часть URL-адреса — строка запроса.)
  • Request.Cookies коллекция предоставляет доступ к файлам cookie, отправленным браузером.

Чтобы получить значение, которое, как вы знаете, содержится в отправленной форме, можно использовать Request["name"]. Кроме того, можно использовать более конкретные версии Request.Form["name"] (для POST запросов) или Request.QueryString["name"] (для GET запросов). Разумеется, name — это имя элемента, который нужно получить.

Имя элемента, который требуется получить, должно быть уникальным в коллекции, которую вы используете. Вот почему Request объект предоставляет подмножества, как Request.Form и Request.QueryString. Предположим, что ваша страница содержит элемент формы с именем userName, а также содержит файл cookie с именем userName. Если вы получаете Request["userName"], неясно, нужно ли значение формы или файл cookie. Тем не менее, если вы получаете Request.Form["userName"] или Request.Cookie["userName"], вы четко указываете, какое значение нужно получить.

Рекомендуется быть конкретным и использовать подмножество Request того, что вы хотите, например Request.Form или Request.QueryString. Для простых страниц, которые вы создаете в этом руководстве, это, вероятно, не имеет значения. Однако при создании более сложных страниц с помощью явной версии Request.Form или Request.QueryString можно избежать проблем, которые могут возникнуть, когда страница содержит форму (или несколько форм), файлы cookie, значения строки запроса и т. д.

Создание запроса с помощью термина поиска

Теперь, когда вы знаете, как получить введенный пользователем поисковый термин, можно создать запрос, использующий его. Помните, что чтобы получить все элементы фильма из базы данных, вы используете SQL-запрос, который выглядит следующим образом:

SELECT * FROM Movies

Чтобы получить только определенные фильмы, необходимо использовать запрос, содержащий Where предложение. Это предложение позволяет установить условие, по которому строки возвращаются запросом. Приведем пример:

SELECT * FROM Movies WHERE Genre = 'Action'

Базовый формат : WHERE column = value. Вы можете использовать разные операторы, помимо =, например, > (больше), < (меньше), <> (не равно), <= (меньше или равно) и т. д., в зависимости от того, что вы ищете.

Если вам интересно, операторы SQL не чувствительны к регистру — SELECT является тем же самым, что и Select (или даже select). Тем не менее, люди часто делают ключевые слова в инструкции SQL прописными, например SELECT и WHERE, чтобы упростить чтение.

Передача поискового термина в качестве параметра

Поиск определенного жанра достаточно просто (WHERE Genre = 'Action'), но вы хотите иметь возможность искать любой жанр, который пользователь вводит. Для этого создайте SQL-запрос, который включает заполнитель для значения, которое нужно искать. Эта команда будет выглядеть следующим образом:

SELECT * FROM Movies WHERE Genre = @0

Заполнитель — это @ символ, за которым следует ноль. Как можно угадать, запрос может содержать несколько заполнителей, и они будут называться @0, @1и @2т. д.

Чтобы настроить запрос и передать его значение, используйте следующий код:

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 , когда злоумышленник отправляет значения на страницу, которая взломает базу данных. (Дополнительные сведения см. в статье о внедрении SQL на веб-сайте MSDN.)

Обновление страницы фильмов с помощью кода поиска

Теперь можно обновить код в файле Movies.cshtml . Чтобы начать, замените код в блоке кода в верхней части страницы следующим кодом:

var db = Database.Open("WebPagesMovies");
var selectCommand = "SELECT * FROM Movies";
var searchTerm = "";

Затем вы передаете запрос в переменную selectCommand, которую вы передадите db.Query позже. Поместив инструкцию 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, код устанавливает selectCommand на другой запрос, а именно на тот, который включает условие Where для поиска жанра. Он также устанавливает searchTerm в значение, которое было передано для поля поиска (что может быть пустым).

Независимо от того, какая инструкция SQL находится в selectCommand, затем вызывается db.Query для выполнения запроса, передавая ему всё, что содержится в searchTerm. Если в searchTerm нет ничего, это не имеет значения, так как в этом случае всё равно нет параметра для передачи значения в selectCommand.

Наконец, код инициализирует вспомогательный WebGrid с помощью результатов запроса, как и раньше.

Вы можете увидеть, что, поместив инструкцию SQL и термин поиска в переменные, вы добавили гибкость в код. Как вы увидите далее в этом руководстве, вы можете использовать эту базовую платформу и продолжать добавлять логику для различных типов поиска.

Тестирование функции поиска по жанру

В WebMatrix запустите страницу Movies.cshtml . Вы увидите страницу с текстовым полем для жанра.

Введите жанр, который вы ввели для одной из записей теста, а затем нажмите кнопку "Поиск". На этот раз вы увидите список только фильмов, которые соответствуют этому жанру:

Страница фильмов после поиска жанра

Введите другой жанр и снова выполните поиск. Попробуйте ввести жанр, используя все строчные буквы или все прописные буквы, чтобы увидеть, что поиск не учитывает регистр.

Запоминание того, что ввёл пользователь

Возможно, вы заметили, что после ввода жанра и щелкнув жанр поиска, вы увидели список для этого жанра. Однако текстовое поле поиска было пустым — иными словами, он не помнил, что вы ввели.

Важно понимать, почему такое поведение происходит. При отправке страницы браузер отправляет запрос на веб-сервер. Когда ASP.NET получает запрос, он создает новый экземпляр страницы, запускает код в нем, а затем снова отображает страницу в браузере. На самом деле страница не знает, что вы просто работали с её предыдущей версией. Единственное, что ему известно, это то, что он получил запрос с некоторыми данными из формы.

Каждый раз, когда вы запрашиваете страницу ( будь то первый раз или отправляя ее), вы получаете новую страницу. Веб-сервер не имеет памяти последнего запроса. Ни ASP.NET этого не делает, ни браузер. Единственным подключением между этими отдельными экземплярами страницы являются все данные, передаваемые между ними. При отправке страницы, например, новый экземпляр страницы может получить данные формы, отправленные предыдущим экземпляром. (Другим способом передачи данных между страницами является использование файлов cookie.)

Формальный способ описать эту ситуацию заключается в том, чтобы сказать, что веб-страницы бездевые. Веб-серверы и сами страницы и элементы на странице не содержат никаких сведений о предыдущем состоянии страницы. Веб-сайт был разработан таким образом, так как поддержание состояния отдельных запросов быстро исчерпает ресурсы веб-серверов, которые часто обрабатывают тысячи, может быть, даже сотни тысяч запросов в секунду.

Поэтому текстовое поле было пустым. После отправки страницы ASP.NET создала новый экземпляр страницы и выполнила код и разметку. В этом коде не было ничего, что указывало бы ASP.NET поместить значение в текстовое поле. Таким образом, ASP.NET не выполнил никаких действий, и текстовое поле было отрисовано без значения.

Есть на самом деле простой способ обойти эту проблему. Жанр, который вы ввели в текстовое поле, доступен вам в коде — он находится в.

Обновите разметку текстового поля так, чтобы атрибут value получал своё значение из searchTerm, как в этом примере:

<input type="text" name="searchGenre" value="@Request.QueryString["searchGenre"]" />

На этой странице вы могли бы также присвоить атрибут value переменной searchTerm, поскольку эта переменная также содержит введенный вами жанр. Но использование объекта для задания атрибута Requestvalue , как показано ниже, является стандартным способом выполнения этой задачи. (Если вы даже хотите сделать это — в некоторых ситуациях может потребоваться отобразить страницу без значений в полях. Все зависит от того, что происходит с приложением.)

Замечание

Значение текстового поля, используемого для паролей, нельзя помнить. Это было бы отверстие безопасности, позволяющее людям заполнять поле пароля с помощью кода.

Снова запустите страницу, введите жанр и нажмите кнопку "Жанр поиска". На этот раз вы видите не только результаты поиска, но и текстовое поле запоминает введенное вами в прошлый раз.

Страница, показывающая, что текстовое поле запомнило предыдущую запись

Поиск любого слова в заголовке

Теперь вы можете искать любой жанр, но вы также можете искать название. Трудно точно подобрать заголовок при поиске, поэтому вместо этого можно искать слово, которое встречается в любом месте заголовка. Для этого в SQL используйте LIKE оператор и синтаксис, как показано ниже:

SELECT * FROM Movies WHERE Title LIKE '%adventure%'

Эта команда получает все фильмы, названия которых содержат "приключение". При использовании LIKE оператора вы включаете подстановочный знак % в рамках термина поиска. Поиск LIKE 'adventure%' означает "начинается с 'приключения'". (Технически это означает "Строка "приключение", за которой следует что угодно".) Аналогичным образом, поисковый термин LIKE '%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 и searchTitle, код устанавливает searchTerm на значение, которое вы хотите найти. Эти блоки кода также устанавливают для selectCommand соответствующую команду SQL для этого поиска.
  • Метод 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>

Дополнительные ресурсы