Серверные элементы управления
Элементы проверки достоверности (валидаторы)
Одной из важных задач HTML-дескриптора <form> является сбор и передача данных у своих элементов управления. Часто Web-страницы запрашивают у пользователя какую-либо информацию, затем сохраняют ее во вспомогательной базе данных. Всегда нужно проверять введенную пользователем информацию на предмет содержания ошибок или злонамеренного кода, которые могут вызвать сбой в работе сайта.
Существует три способа проверки данных пользователя на корректность:
- Проверка данных на клиенте
- Проверка данных на сервере
- Проверка данных и на клиенте и на сервере
Проверка данных на клиенте осуществляется с помощью специальных методов на языке сценариев JavaScript. Недостаток таких методов состоит в том, что броузер клиента может не поддерживать JavaScript или клиент намеренно отключил в броузере эту поддержку для безопасности. Таким образом, на клиентскую проверку полагаться не стоит, хотя она реализуется проще и выполняется быстрее.
Проверка на сервере не зависит от настроек клиента и ее выполнение можно предусмотреть всегда. Недостаток такой проверки состоит в том, что данные прежде должны поступить на сервер, и только после этого их можно проверять. При обнаружении некорректных данных их нужно отправить назад клиенту с сопроводительным предупреждением. Такие никчемные пересылки могут повторяться многократно до тех пор, пока мы не дождемся корректных данных. Это может занять много времени.
Самым эффективным будет реализация проверки и на клиенте и на сервере. При таком способе, если на клиенте работает JavaScript, то при обнаружении ошибки обращение к серверу отсутствует и клиенту сразу на месте выдается предупреждение. В случае, если JavaScript не работает, то данные проверяются на сервере.
В Visual Studio 2005 на вкладке Validation панели Toolbox содержится ряд элементов, специально предназначенных для выполнения проверки данных, а именно
- RequiredFieldValidator - контролирует, не пуст ли проверяемый элемент управления при отправке формы
- CompareValidator - проверяет, соответствует ли значение связанного элемента управления определенной операции сравнения (больше, меньше и т.д.) с другой константой
- RangeValidator - контролирует, находится ли значение связанного элемента управления в заданном диапазоне. Диапазон может быть числом, датой или строкой
- RegularExpressionValidator - проверяет, соответствует ли значение связанного элемента управления определенному регулярному выражению
- CustomValidator - позволяет определить собственную логику проверки достоверности на JavaScript
- ValidationSummary - отображает на странице или всплывающем окне итоговую информацию с сообщениями о найденных ошибках проверки достоверности
Эти валидаторы позволяют организовать проверку данных как на клиентской стороне, так и на сервере. С их помощью можно формировать сообщения об ошибках. Некоторые элементы управления можно проверить по содержимому свойства Value, которое является скрытым атрибутом и в броузере не отображается.
Элемент RequiredFieldValidator
Самым простым валидатором является элемент RequiredFieldValidator. Он проверяет, не является ли связанный элемент пустым. Можно задать и предопределенное значение для проверки совпадения через свойство InitialValue. В этом случае проверка считается неудачной, если содержимое элементов управления совпадает с InitialValue. Валидатор RequiredFieldValidator связывается с проверяемым элементом через свойство ControlToValidate.
Индивидуальное сообщение об ошибке в валидаторе можно задать в свойстве Text или разместить между открывающим и закрывающим дескрипторами валидатора. Например
<asp:TextBox ID="TextBox1" runat="server"></asp:TextBox> <asp:RequiredFieldValidator ID="Val1" runat="server" ControlToValidate="TextBox1" Width="217px"> Заполните поле TextBox1 </asp:RequiredFieldValidator> <br /> <asp:TextBox ID="TextBox2" runat="server"></asp:TextBox> <asp:RequiredFieldValidator ID="Val2" runat="server" ControlToValidate="TextBox2" Width="217px" Text="Заполните поле TextBox2" />
Если мы хотим выдать сообщения о всех ошибках сразу, то это делается через элемент ValidationSummary, а предупреждение от текущего валидатора нужно записать в его свойство ErrorMessage.
Разместить элемент RequiredFieldValidator можно в любом месте страницы, где мы хотим видеть сообщение об ошибке. Использование отведенного места для вывода сообщения об ошибке определяется свойством Display валидатора, которое может принимать следующие значения:
- Dynamic - не занимать место, если нет ошибки
- Static - держать место независимо от ошибки (установлено по умолчанию)
- None - валидатор есть, но место не занимает и ошибки не отображает, а скрытно контролирует элемент управления для элемента суммарных ошибок ValidationSummary
Ниже приведен пример, в котором валидаторы RequiredFieldValidator следят за заполнением текстовых полей и предупреждают пользователя. Валидаторы различаются значением свойства Display.
<%@ Page Language="C#" AutoEventWireup="true" %> <html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server"> <title>Untitled Page</title> </head> <body> <form id="form1" runat="server"> Фамилия: <asp:TextBox ID="TextBox1" runat="server"></asp:TextBox> <asp:RequiredFieldValidator ID="Val1" runat="server" ControlToValidate="TextBox1" Text="Заполните поле TextBox1" Display="Dynamic" /> !Dynamic! <br /> Имя: <asp:TextBox ID="TextBox2" runat="server"></asp:TextBox> <asp:RequiredFieldValidator ID="Val2" runat="server" ControlToValidate="TextBox2" Text="Заполните поле TextBox2" /> !Static! <br /> Отчество: <asp:TextBox ID="TextBox3" runat="server"></asp:TextBox> <asp:RequiredFieldValidator ID="Val3" runat="server" ControlToValidate="TextBox3" Text="Заполните поле TextBox3" Display="None" /> !None! <br /> <asp:Button ID="Button1" runat="server" Text="Зарегистрироваться" /> </form> </body> </html>
Страница с приведенным кодом генерирует на броузер следующий результат
Если исследовать поведение страницы, то можно сделать несколько важных выводов:
- При первом запросе страницы клиенту предоставляются пустые текстовые поля и сообщений об этом нет.
- При нажатии кнопки инициации постинга против пустых полей появляются предупреждающие сообщения и форма не отсылается. Это работает JavaScript, который сгенерировали валидаторы страницы.
- Валидатор с атрибутом Display="Dynamic" при скрытии сообщения сразу освобождает место. Валидаторы с другими значениями этого атрибута ведут себя так, как говорилось ранее.
- Кнопка обратной отсылки начинает действовать только тогда, когда все поля будут непустыми.
Попробуйте отключить в своем броузере поддержку активных сценариев. Для этого:
-
Выполните команду броузера Tools/Internet Options... Откроется окно Internet Options, в котором перейдите на вкладку Security
-
Выделите на вкладке зону Local internet и щелкните на кнопке Custom Level
-
В открывшемся окне отметьте переключатель Scripting/Active scripting/Disable, тем самым отключится поддержка броузером сценариев JavaScript
Теперь можно увидеть, что валидаторы срабатывают только после постинга, поскольку обрабатываются на сервере.
Есть общее булево статическое свойство Page.IsValid для страницы. Если его значение равно true, значит проверка всех валидаторов страницы прошла успешно. Небольшой пример демонстрирует применение этого свойства страницы. В нем, если проверка прошла успешно, то пользователь регистрируется (условно).
<%@ Page Language="C#" %> <script runat="server"> protected void btnRegister_Click(object sender, EventArgs e) { if(Page.IsValid) { // Все введено, можно регистрировать Label1.Text = "Вы зарегистрированы"; Label1.ForeColor = System.Drawing.Color.White; Label1.BackColor = System.Drawing.Color.Green; } } </script> <html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server"> <title>Registered Page</title> </head> <body> <form id="form1" runat="server"> <div> <asp:Label ID="Label1" runat="server" Text="Просим зарегистрироваться" /><br /> <br /> First Name: <asp:TextBox ID="tbFirst" runat="server" /> <asp:RequiredFieldValidator ID="RequiredFieldValidator1" runat="server" ControlToValidate="tbFirst" Text="Введите первое имя" /><br /> Last Name: <asp:TextBox ID="tbLast" runat="server" /> <asp:RequiredFieldValidator ID="RequiredFieldValidator2" runat="server" ControlToValidate="tbLast" Text="Введите второе имя" /><br /> <br /> <asp:Button ID="btnRegister" runat="server" OnClick="btnRegister_Click" Text="Register" /> </div> </form> </body> </html>
Элемент управления RequiredFieldValidator может использоваться не только с текстовыми полями, но и с другими элементами управления, например, CheckBox, CheckBoxList, RadioButton, RadioButtonList, DropDownList, ListBox. Приведем пример контроля за выбором в списке с применением свойства InitialValue. Будем использовать скрытый валидатор, а его сигнал будем проверять по свойству Page.IsValid. Валидатор будет устанавливать это свойство в false (сигнал ошибки), если неотображаемый атрибут Value выбранного пункта списка совпадет по значению со свойством InitialValue валидатора. Код страницы с примером будет таким
<%@ Page Language="C#" %> <script runat="server"> protected void Button1_Click(object sender, EventArgs e) { if (!Page.IsValid) { // Срабатывает при отключенной поддержке JavaScript // в броузере. Иначе JavaScript на клиенте // не разрешает постинг, пока есть неправильный выбор Label1.Text = "Эта опция запрещена!"; } else { Label1.Text = "Разрешенный выбор!"; } } </script> <html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server"> <title>ListValidate</title> </head> <body> <form id="form1" runat="server"> <div> <asp:Label ID="Label1" runat="server" Text="Выделите опцию" /> <br /> <asp:DropDownList ID="DropDownList1" runat="server"> <asp:ListItem Value="Невыделяемая">Пустышка</asp:ListItem> <asp:ListItem>Опция 1</asp:ListItem> <asp:ListItem>Опция 2</asp:ListItem> <asp:ListItem>Опция 3</asp:ListItem> </asp:DropDownList> <asp:RequiredFieldValidator ID="RequiredFieldValidator1" runat="server" ControlToValidate="DropDownList1" Display="None" InitialValue="Невыделяемая" /> <br /> <asp:Button ID="Button1" runat="server" Text="Submit" OnClick="Button1_Click" /> </div> </form> </body> </html>
В последнем примере мы должны понимать, что при включенной на клиенте поддержке JavaScript предупреждение об ошибке никогда не будет выдано кодом страницы, потому что постинг броузером будет заблокирован, пока пользователь не сделает правильный выбор. Обратите внимание на настройки валидатора. Он не сможет выдать текстовое предупреждение пользователю, потому что мы сделали его неотображаемым ( Display="None" ) и удалили за ненадобностью свойства-сообщения ErrorMessage и Text.