Явная валидация модели
Наиболее очевидный способ валидации модели – проверить данные в соответствующем методе действия. В листинге 23-5 показано, как мы добавили явную проверку для каждого свойства, определенного в классе Appointment
, в HttpPost-версии метода действия MakeBooking
.
Листинг 23-5: Осуществляем явную валидацию модели
[HttpPost]
public ViewResult MakeBooking(Appointment appt)
{
if (string.IsNullOrEmpty(appt.ClientName))
{
ModelState.AddModelError("ClientName", "Please enter your name");
}
if (ModelState.IsValidField("Date") && DateTime.Now > appt.Date)
{
ModelState.AddModelError("Date", "Please enter a date in the future");
}
if (!appt.TermsAccepted)
{
ModelState.AddModelError("TermsAccepted", "You must accept the terms");
}
if (ModelState.IsValid)
{
// statements to store new Appointment in a
// repository would go here in a real project
return View("Completed", appt);
}
else
{
return View();
}
}
Мы проверяем значения, которые механизм связывания присвоил свойствам объекта параметра, и регистрируем ошибки, которые находим в свойстве ModelState
(его наш контроллер наследует от базового класса). Например, свойство ClientName
мы проверяем таким образом:
if (string.IsNullOrEmpty(appt.ClientName)) {
ModelState.AddModelError("ClientName", "Please enter your name");
}
Мы хотим, чтобы пользователь ввел значение для этого свойства, поэтому используем статический метод string.IsNullOrEmpty
, чтобы его проверить. Если мы не получили значение, то с помощью метода ModelState.AddModelError
указываем имя свойства, с которым возникла проблема (ClientName
), и сообщение, которое будет показано пользователю, чтобы помочь ему исправить проблему (Please enter your name
).
С помощью свойства ModelState.IsValidField
мы можем проверить, смог ли механизм связывания присвоить значение. Мы применяем его в свойстве Date
, чтобы убедиться, что механизм связывания смог проанализировать значение, полученное от пользователя; нет никакого смысла выполнять дополнительные проверки или регистрировать дополнительные ошибки, если значение не могло быть выделено из данных запроса.
После того как мы провели валидацию всех свойств в объекте модели, мы проверяем свойство ModelState.IsValid
на наличие ошибок. Если во время проверок мы вызвали метод Model.State.AddModelError
, или у механизма связывания возникли проблемы с созданием объекта Appointment
, то этот метод возвращает true
.
if (ModelState.IsValid)
{
// statements to store new Appointment in a
// repository would go here in a real project
return View("Completed", appt);
}
else
{
return View();
}
Если в свойстве IsValid
нет ошибок, то наш объект Appointment
является действительным, и мы можем визуализировать представление Completed.cshtml
(и, в реальном проекте, сохранить объект Appointment
в хранилище). Если свойство IsValue
возвращает false
, то мы знаем, что у нас есть проблема, и вызываем метод View
, который визуализирует представление по умолчанию.
Отображаем ошибки валидации пользователю
Может показаться странным, что мы обрабатываем ошибки валидации с помощью метода View
, но шаблонные вспомогательные методы, которые мы использовали для создания элементов ввода в представлении MakeBooking.cshtml
, проверяют модель представления на наличие ошибок валидации.
Если в свойстве появилась ошибка, вспомогательный метод добавляет к элементу ввода класс CSS под названием input-validation-error
. Файл ~/Content/Site.css
содержит определение по умолчанию для этого стиля, которое выглядит следующим образом:
.input-validation-error {
border: 1px solid #f00;
background-color: #fee;
}
Он устанавливает красную рамку и розовый фон для элемента, в котором есть ошибка. Чтобы проверить работу явной валидации, запустите приложение, перейдите по ссылке /Home/MakeBooking
и нажмите кнопку Make Booking
, не вводя данные в форму. Результат показан на рисунке 23-2.
Подсказка
Если вы хотите написать собственные вспомогательные методы, которые поддерживают валидацию, изучите исходный код класса
System.Mvc.Web.Html.InputExtensions
, чтобы понять, как это сделаеть. Вкратце скажем, что классSystem.Web.Mvc.HtmlHelper
определяет методGetModelStateValue
, который позволяет проверить, есть ли ошибки валидации для конкретного свойства. Есть и дополнительные методы, которые позволяют легко получить необходимый CSS и сообщения об ошибках для создания предупреждения пользователю.
Рисунок 23-2: Поля с ошибками подсвечены

Применяем стили к чекбоксам
Некоторые браузеры, в том числе Chrome и Firefox, игнорируют стили, примененные к чекбоксам, в результате чего элементы формы будут выглядеть непоследовательно. Чтобы решить эту проблему, можно заменить шаблон
Boolean
для элементовeditor
пользовательским шаблоном~/Views/Shared/EditorTemplates/Boolean.cshtml
и заключить чекбокс в элементdiv
. Мы используем следующий шаблон, который вы можете приспособить для своего приложения:Этот шаблон поместит чекбокс в элемент
div
, к которому будет применен стильinput-validation-error
, если возникнут какие-либо ошибки модели, связанные с тем свойством, к которому был применен шаблон. Вы можете узнать больше о замене шаблоновeditor
в главе 20.
Если вы отправите форму без данных, ошибки будут подсвечены для свойств ClientName
и TermsAccepted
. Значение по умолчанию для свойства Date
является действительным, поэтому ошибка валидации не возникает.
Пользователь не увидит представление Completed.cshtml
, пока не отправит форму с данными, которые могут быть проанализированы браузером модели (model browser), который передает операторы явной валидации в метод действия MakeBooking
. В противном случае отправка формы будет визализировать представление MakeBooking.cshtml
с текущими ошибками валидации.