ASP.NET MVC 4
Адам Фриман
Отображение сообщений валидации
CSS стили, которые применяются шаблонными вспомогательными методами к элементам ввода, указывают на проблему с полем, но не сообщают пользователю, в чем эта проблема заключается. К счастью, для этого существуют другие вспомогательные методы. В листинге 23-6 показан один из таких методов, который мы применили к представлению MakeBooking
(так как именно оно демонстрирует ошибки валидации пользователю).
Листинг 23-6: Используем вспомогательный метод ValidationSummary
<h4>Book an Appointment</h4>
@using (Html.BeginForm())
{
@Html.ValidationSummary()
<p>Your name: @Html.EditorFor(m => m.ClientName)</p>
<p>Appointment Date: @Html.EditorFor(m => m.Date)</p>
<p>@Html.EditorFor(m => m.TermsAccepted) I accept the terms & conditions</p>
<input type="submit" value="Make Booking" />
}
Вспомогательный метод Html.ValidationSummary
добавляет сообщение об ошибках валидации, которые были зарегистрированы на отображаемой пользователю странице. Если ошибок нет, то вспомогательный метод не генерирует HTML. На рисунке 23-3 показан результат применения этого метода. Мы очистили поля ввода и отправили форму.
Рисунок 23-3: Отображение сообщения валидации
Примечание
Для свойства
Date
мы используем значения в американском формате датыmonth/day/year
. Если вы находитесь в другой стране, то можете ввести допустимые даты в местном формате (например,day/month/year
, который широко используется в Европе) или добавить для этого проекта строку<globalization culture="en-US" uiCulture="en-US"/>
в элементsystem.web
в файлеWeb.config
, чтобы приложение использовало формат даты US.
В сообщении валидации отображается информация об ошибках, которые были зарегистрированы в ModelState
в методе действия MakeBooking
. Этот вспомогательный метод генерирует следующий HTML:
<div class="validation-summary-errors" data-valmsg-summary="true">
<ul>
<li>Please enter your name</li>
<li>Please enter a date in the future</li>
<li>You must accept the terms</li>
</ul>
</div>
Ошибки выводятся в виде списка в элементе div
, к которому применен стиль validation-summary-errors
. Этот стиль определен в ~/Content/Site.css
и по мере необходимости может быть изменен. По умолчанию стиль выделяет текст сообщений об ошибках полужирным и красным:
.validation-summary-errors {
font-weight: bold;
color: #f00;
}
Для метода ValidationSummary
существует несколько перегруженных версий; наиболее полезные из них показаны в таблице 23-1. Некоторые из этих версий позволяют указать, что нужно отображать только ошибки уровня модели (model-level errors). Ошибки, которые до сих пор были зарегистрированы в ModelState
, относятся к уровню свойства (property-level errors) и означают, что для данного свойства указано недействительное значение; если его изменить, проблема будет решена.
Таблица 23-1: Полезные перегруженные версии вспомогательного метода ValidationSummary
Перегруженный метод | Описание |
Html.ValidationSummary() |
Генерирует сообщения для всех ошибок валидации. |
Html.ValidationSummary(bool) |
Если параметр bool содержит true , то отображаются только ошибки уровня модели (см. пояснение после таблицы). Если параметр содержит false , то отображаются все ошибки. |
Html.ValidationSummary(string) |
Отображает сообщение (содержащееся в параметре string ) перед сообщениями обо всех ошибках валидации. |
Html.ValidationSummary(bool, string) |
Отображает сообщение перед сообщениями об ошибках валидации. Если параметр bool содержит true , то отображаются только ошибки уровня модели. |
С другой стороны, ошибки уровня модели можно использовать, если проблемы возникают из-за взаимодействия двух и более значений свойств. Простой пример: давайте представим, что клиенту по имени Джо нельзя записываться на прием по понедельникам. В листинге 23-7 показано, как для этого правила можно создать явное условие валидации в методе действия MakeBooking
и вывести сообщение об ошибке валидации уровня модели.
Листинг 23-7: Ошибка валидации уровня модели
[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.IsValidField("ClientName") && ModelState.IsValidField("Date")
&& appt.ClientName == "Joe" && appt.Date.DayOfWeek == DayOfWeek.Monday)
{
ModelState.AddModelError("", "Joe cannot book appointments on Mondays");
}
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.IsValidField
, что значения свойств ClientName
и Date
действительны.
Это означает, что мы не будем генерировать ошибку уровня модели, пока не проведем успешную валидацию предыдущих свойств. Чтобы зарегистрировать ошибку уровня модели, мы передаем пустую строку (""
) в качестве первого параметра в метод ModelState.AddModelError
, например:
ModelState.AddModelError("", "Joe cannot book appointments on Mondays");
Далее мы обновим файл MakeBooking.cshtml
, чтобы использовать в нем версию вспомогательного метода ValidationSummary
, которая принимает параметр bool
и будет отображать только ошибки уровня модели, как показано в листинге 23-8.
Листинг 23-8: Обновляем представление MakeBooking.cshtml
, чтобы отображать только ошибки уровня модели
@model ModelValidation.Models.Appointment
@{
ViewBag.Title = "Make A Booking";
}
<h4>Book an Appointment</h4>
@using (Html.BeginForm())
{
@Html.ValidationSummary(true)
<p>Your name: @Html.EditorFor(m => m.ClientName)</p>
<p>Appointment Date: @Html.EditorFor(m => m.Date)</p>
<p>@Html.EditorFor(m => m.TermsAccepted) I accept the terms & conditions</p>
<input type="submit" value="Make Booking" />
}
Результат этих изменений показан на рисунке 23-4, где мы ввели имя Джо и указали дату, которая выпадает на понедельник.
Рисунок 23-4: Отображение сообщения валидации для ошибок уровня модели
Как видно из рисунка, есть две ошибки валидации. Первая - это ошибка уровня модели, которая возникает, когда Джо пытается записаться на прием в понедельник. Вторая появляется из-за того, что не отмечен чекбокс для условий пользовательского соглашения. Так как в сообщении валидации мы отображаем только ошибки уровня модели, пользователь не увидит никаких сведений о второй проблеме.
Отображаем сообщения валидации уровня свойства
Мы отображаем только сообщения об ошибках уровня модели потому, что ошибки уровня свойства можно отображать рядом с соответствующими полями. Таким образом, мы не хотим дублировать сообщения, относящиеся к отдельным свойствам. В листинге 23-9 показано обновленное представление MakeBooking.cshtml
, которое отображает ошибки уровня модели сверху и ошибки уровня свойства рядом с соответствующим полем ввода.
Листинг 23-9: Используем сообщения об ошибках для конкретного свойства
@model ModelValidation.Models.Appointment
@{
ViewBag.Title = "Make A Booking";
}
<h4>Book an Appointment</h4>
@using (Html.BeginForm())
{
@Html.ValidationSummary(true)
<p>@Html.ValidationMessageFor(m => m.ClientName)</p>
<p>Your name: @Html.EditorFor(m => m.ClientName)</p>
<p>@Html.ValidationMessageFor(m => m.Date)</p>
<p>Appointment Date: @Html.EditorFor(m => m.Date)</p>
<p>@Html.ValidationMessageFor(m => m.TermsAccepted)</p>
<p>@Html.EditorFor(m => m.TermsAccepted) I accept the terms & conditions</p>
<input type="submit" value="Make Booking" />
}
Вспомогательный метод Html.ValidationMessageFor
отображает ошибки валидации для одного свойства модели. Результат его применения в представлении MakeBooking
показан на рисунке 23-5.
Рисунок 23-5: Используем вспомогательный метод для отображения сообщений валидации для одного свойства