Книга: ASP.NET MVC Framework
Индикаторы корректности введенных данных
Разделы на этой странице:
Индикаторы корректности введенных данных
Пользователям свойственно ошибаться при вводе данных, и приложению необходимо уведомлять пользователя о допущенных ошибках и конкретных полях формы, которые заполнены некорректно. Для этого существуют два вспомогательных метода: Html.validationMessage(),
который выводит сообщение, относящееся к определенному полю на форме, и Html.validationSummary (),
который выводит общую информацию по ошибкам, допущенным при заполнении формы.
Работа этих вспомогательных методов основана на коллекции ModelState
, которая упоминалась ранее. В этой коллекции на этапе проверки корректности данных сохраняется информация об ошибках, связанных с конкретными полями формы. Пример действия контроллера, выполняющего проверку корректности введенных данных (валидацию), приведен в листинге 5.7.
Листинг 5.7. Пример валидации данных
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Edit(Product obj, int id)
{
if (obj.UnitsOnOrder < 0)
ModelState.AddModelError("UnitsOnOrder",
"Количество заказанных единиц товара не может
быть отрицательным.");
if (obj.UnitsInStock < 0)
ModelState.AddModelError("UnitsInStock",
"Количество единиц товара на складе должно быть не
отрицательным.");
if (obj.UnitPrice <= 0)
ModelState.AddModelError("UnitPrice",
"Цена должна быть больше нуля.");
if (!ModelState.IsValid)
{
// есть ошибки, еще раз
// показать форму редактирования
return View(obj);
}
else
{
// ошибок нет, сохранить
db.SaveProduct(obj);
return RedirectToAction("Index");
}
}
Процесс валидации прост — выполняется проверка условий и в случае наличия ошибок в коллекцию Modelstate
добавляется информация в виде пары "идентификатор элемента — описание допущенной ошибки". Если в коллекцию Modelstate
добавлена хотя бы одна такая пара, то значение свойства Modelstate.isValid
будет установлено в false. В случае если ошибки допущены, то необходимо снова отобразить то же представление, которое использовалось для радактирования данных, и передать ему те данные, которые были введены пользователем на предыдущем шаге. Пример такого представления, работающего с кодом, описанным в листинге 5.7, показан в листинге 5.8, там же приведено строго типизированное представление, в качестве модели использующее класс Product
.
Листинг 5.8. Представление Edit.aspx
<%@ Page Title="" Language="C#"
MasterPageFile="~/Views/Shared/Site.Master"
Inherits="System.Web.Mvc.ViewPage<MvcViewsDemo.Models.Product>" %>
<asp:Content ContentPlaceHolderID="TitleContent"
runat="server">
Edit
</asp:Content>
<asp:Content ContentPlaceHolderID="MainContent" runat="server">
<h2>
Редактирование сведений о товаре
</h2>
<%= Html.ValidationSummary("npи редактировании сведений
о товаре произошли ошибки.") %>
<% using (Html.BeginForm())
{%>
<fieldset>
<legend>Редактирование сведений о товаре</legend>
<p>
<label for="ProductID">
Код продукта:
</1аЬе1>
<%= Model.ProductID.ToString() %>
<%= Html.Hidden("ProductId", Model.ProductID)%>
</p>
<p>
<label for="ProductName">
Название:
</label>
<%= Html.TextBox("ProductName", Model.ProductName) %>
<%= Html.ValidationMessage("ProductName", "*") %>
</p>
<p>
<label for="UnitPrice">
Цена:
</label>
<%= Html.TextBox("UnitPrice",
String.Format("{0:F}", Model.UnitPrice)) %>
<%= Html.ValidationMessage("UnitPrice", "*") %>
</p>
<p>
<label for="UnitsInStock">
На складе:
</label>
<%= Html.TextBox("UnitsInStock", Model.UnitsInStock) %>
<%= Html.ValidationMessage("UnitsInStock", "*") %>
</p>
<p>
<label for="UnitsOnOrder">
Заказано:
</label>
<%= Html.TextBox("UnitsOnOrder", Model.UnitsOnOrder) %>
<%= Html.ValidationMessage("UnitsOnOrder", "*") %>
</p>
<p>
<input type="submit" value="Save" />
</p>
</fieldset>
<% } %>
<div>
<%=Html.ActionLink("K списку товаров", "Index") %>
</div>
</asp:Content>
В листинге 5.8 методы Html.ValidationMessage()
вызываются co вторым строковым параметром, указывающим сообщение, которое должно быть отображено пользователю в случае наличия ошибки в коллекции ModelState
. В результате форма, заполненная с ошибками, будет выглядеть так, как показано на рис. 5.2.
Для того чтобы сообщение об ошибке было выведено непосредственно в месте вызова метода Html.ValidationMessage()
, метод нужно вызывать без указания второго параметра Html.ValidationMessage("UnitPrice")
. Результат приведен на рис. 5.3.
Стоит отметить, что если в коде представления не используется строготипизированная привязка к свойствам модели, то привязка к данным осуществляется автоматически, и в этом случае при возникновении ошибок нет необходимости передавать объект модели представлению через метод View(),
как это было сделано в листинге 5.7. То есть фрагмент кода из листинга 5.7 может быть написан так, как указано далее. Листинг 5.9 демонстрирует код представления, не использующего привязку к свойствам объекта модели Model
.
if (IModelState.IsValid)
{
// есть ошибки, еще раз
// показать форму редактирования
return View();
}
Листинг 5.9. Представление Edit.aspx без привязки к свойствам объекта Model
<%@ Page Title="" Language="C#"
MasterPageFile="~/Views/Shared/Site.Master"
Inherits="System.Web.Mvc.ViewPage<MvcViewsDemo.Models.Product>" %>
<asp:Content ContentPlaceHolderID="TitleContent" runat="server">
Edit
</asp:Content>
<asp:Content ContentPlaceHolderID="MainContent" runat="server">
<h2>
Редактирование сведений о товаре
</h2>
<%= Html.ValidationSummary("при редактировании сведений
о товаре произошли ошибки.") %>
<% using (Html.BeginForm())
{%>
<fieldset>
<legend>Редактирование сведений о товаре</legend>
<p>
<label for="ProductID">
Код продукта:
</label>
<%= ViewData.Eval("ProductID") %>
<%= Html.Hidden("ProductID")%>
</p>
<p>
<label for="ProductName">
Название:
</label>
<%= Html.TextBox("ProductName") %>
<%= Html.ValidationMessage("ProductName") %>
</p>
<p>
<label for="UnitPrice">
Цена:
</label>
<%= Html.TextBox("UnitPrice") %>
<%= Html.ValidationMessage("UnitPrice") %>
</p>
<p>
<label for="UnitsInStock">
На складе:
</label>
<%= Html.TextBox("UnitsInStock") %>
<%= Html.ValidationMessage("UnitsInStock") %>
</p>
<p>
<label for="UnitsOnOrder">
Заказано:
</label>
<%= Html.TextBox("UnitsOnOrder") %>
<%= Html.ValidationMessage("UnitsOnOrder") %>
</p>
<p>
<input type="submit" value="Save" />
</p>
</fieldset>
<% } %>
<div>
<%=Html.ActionLink("K списку товаров", "Index") %>
</div>
</asp:Content>
Примечание
Важно обратить внимание, что при использовании кода, аналогичного приведенному в листинге 5.9, поиск значений элементов формы будет осуществляться через ViewData.Eval(),
и значение ViewData["SomeProperty"]
имеет больший приоритет, чем ViewData.Model.SomeProperty
. Поэтому, во избежание трудноуловимых ошибок, при создании кода контроллера стоит с особенной тщательностью относиться к тому, как передаются данные — через свойства объекта-модели или через коллекцию ViewData
.
***************************
- Резервное копирование базы данных InterBase
- Firebird РУКОВОДСТВО РАЗРАБОТЧИКА БАЗ ДАННЫХ
- Резервное копирование многофайловых баз данных
- Восстановление из резервных копий многофайловых баз данных
- Владелец базы данных
- ЧАСТЬ IV. База данных и ее объекты.
- Перевод базы данных InterBase 6.x на 3-й диалект
- Типы данных для работы с датой и временем
- Практическая работа 53. Запуск Access. Работа с объектами базы данных
- Обзор основных причин повреждения базы данных
- Ошибки проектирования базы данных
- Профилактика повреждений баз данных InterBase