Общие сведения о веб-страницы ASP.NET — основные сведения о формах HTML

; автор — Том ФитцМакен (Tom FitzMacken)

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

Из этого руководства вы узнаете, как выполнять такие задачи:

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

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

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

Что вы создадите

В предыдущем руководстве вы создали базу данных, добавили в нее данные, а затем использовали вспомогательное 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 Forms and Input на сайте W3Schools.)

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

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

Совет

HTML5 и формы ввода

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

веб-страницы ASP.NET поддерживает ввод HTML5 в той степени, в которой это делает браузер пользователя. Представление о новых атрибутах элемента <input> в HTML5 см. в разделе Атрибут входного> типа 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 метод отправки изменений на сервер. Вы увидите это в следующем руководстве еще раз.)

Запустите страницу. Хотя вы не определили поведение для формы, вы можете увидеть, как она выглядит:

Страница

Введите в текстовое поле значение, например "Comedy". Затем щелкните Поиск жанра.

Запишите URL-адрес страницы. Так как атрибуту getэлемента method присваивается <form> значение , введенное значение теперь является частью строки запроса в URL-адресе следующим образом:

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

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

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

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

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

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

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

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

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

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

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

В простом английском языке все 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 ничего не делали, и текстовое поле отображалось без значения в нем.

На самом деле есть простой способ обойти эту проблему. Жанр, введенный в текстовое поле, доступен в коде — в Request.QueryString["searchGenre"].

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

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

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

Примечание

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

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

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

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

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

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

Эта команда получает все фильмы, названия которых содержат "adventure". При использовании LIKE оператора вы включаете подстановочный знак % в поле поиска. Поиск LIKE 'adventure%' означает "начиная с "adventure". (Технически это означает "строка "приключение", за которым следует что-нибудь.) Аналогичным образом, условие LIKE '%adventure' поиска означает "все, за чем следует строка "adventure", что является еще одним способом сказать", заканчивающийся на "adventure".

Таким образом, поисковый запрос LIKE '%adventure%' означает "с "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>

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