Tag-хелперы валидации и стилизация ошибок

Последнее обновление: 08.04.2022

Для определения полей для вывода ошибок валидации применяются специальные хелперы. Рассмотрим их применение на примере следующей модели Person:

using System.ComponentModel.DataAnnotations;

namespace MvcApp.Models
{
    public class Person
    {
        [Required(ErrorMessage = "Не указано имя")]
        public string? Name { get; set; }


        [Required(ErrorMessage = "Не указан электронный адрес")]
        public string? Email { get; set; }

        [Required(ErrorMessage = "Не указан возраст")]
        [Range(1, 100)]
        public int Age { get; set; }
    }
}

ValidationMessageTagHelper

Для валидации на стороне клиента применяется класс ValidationMessageTagHelper. Данный tag-хелпер определяется с помощью применения к элементу <span > атрибута asp-validation-for:

<span asp-validation-for="имя_свойства_модели"></span>

Атрибут asp-validation-for в качестве значения принимает название свойства модели, для которого будет выводиться сообщение об ошибке валидации. Соответственно для каждого поля ввода мы можем предусмотреть подобный хелпер для вывода ошибок валидации. Например, форма для ввода значений для выше определенной модели Person:

@model MvcApp.Models.Person
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers

<form method="post">
    <div>
        <p>
            <label asp-for="Name">Name</label><br />
            <input type="text" asp-for="Name" />
            <span asp-validation-for="Name"  />
        </p>
        <p>
            <label asp-for="Email">Email</label><br />
            <input type="text" asp-for="Email" />
            <span asp-validation-for="Email"  />
        </p>
        <p>
            <label asp-for="Age">Age</label><br />
            <input asp-for="Age" />
            <span asp-validation-for="Age" />
        </p>
        <p>
            <input type="submit" value="Send"  />
        </p>
    </div>
</form>

<script src="https://ajax.aspnetcdn.com/ajax/jQuery/jquery-3.5.1.min.js"></script>
<script src="https://ajax.aspnetcdn.com/ajax/jquery.validate/1.17.0/jquery.validate.min.js"></script>
<script src="https://ajax.aspnetcdn.com/ajax/jquery.validation.unobtrusive/3.2.10/jquery.validate.unobtrusive.min.js"></script>

Например, возьмем tag-хелпер, который применяется для вывода ошибок для свойства Name:

<span asp-validation-for="Name"  />

Данный элемент span будет генерировать следующую разметку:

<span class="field-validation-valid" data-valmsg-for="Name" data-valmsg-replace="true"></span>

ValidationSummaryTagHelper

Другой tag-хелпера - ValidationSummaryTagHelper применяется для отображения сводки ошибок валидации. Он применяется к элементу <div> в виде атрибута asp-validation-summary:

<div asp-validation-summary="ModelOnly"/>

В качестве значения атрибут asp-validation-summary принимает одно из значений перечисления ValidationSummary:

  • None: ошибки валидации не отображаются

  • ModelOnly: отображаются только ошибка валидации уровня модели, ошибки валидации для отдельных свойств не отображаются

  • All: отображаются все ошибки валидации

На выходе тег-хелпер будет генерировать следующий код:

<div class="validation-summary-valid" data-valmsg-summary="true">
	<ul>
		<li style="display:none"></li>
	</ul>
</div>

При возникновении ошибок в список <ul> добавляются все сообщения об ошибках.

Теперь применим ValidationSummaryTagHelper и для этого для модели Person определим следующее представление:

@model MvcApp.Models.Person
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers

<form method="post">
    <div asp-validation-summary="All"></div>
        <p>
            <label asp-for="Name">Name</label><br />
            <input type="text" asp-for="Name" />
            <span asp-validation-for="Name"  />
        </p>
        <p>
            <label asp-for="Email">Email</label><br />
            <input type="text" asp-for="Email" />
            <span asp-validation-for="Email"  />
        </p>
        <p>
            <label asp-for="Age">Age</label><br />
            <input asp-for="Age" />
            <span asp-validation-for="Age" />
        </p>
        <p>
            <input type="submit" value="Send"  />
        </p>
</form>

<script src="https://ajax.aspnetcdn.com/ajax/jQuery/jquery-3.5.1.min.js"></script>
<script src="https://ajax.aspnetcdn.com/ajax/jquery.validate/1.17.0/jquery.validate.min.js"></script>
<script src="https://ajax.aspnetcdn.com/ajax/jquery.validation.unobtrusive/3.2.10/jquery.validate.unobtrusive.min.js"></script>

И в случае некорректного ввода в верху формы отобразятся ошибки валидации:

хелперы валидации ValidationMessageTagHelper и ValidationSummaryTagHelper в ASP.NET Core MVC и C#

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

Например, в контроллере в методе, который получает данную форму, добавим дополнительную проверку данных:

using Microsoft.AspNetCore.Mvc;
using MvcApp.Models;  // пространство имен класса Person

namespace MvcApp.Controllers
{
    public class HomeController : Controller
    {
        public IActionResult Create() => View();

        [HttpPost]
        public IActionResult Create(Person person)
        {
            if (person.Name == "admin")
                ModelState.AddModelError("Name", "admin - запрещенное имя.");
            if (ModelState.IsValid)
                return Content($"{person.Name} - {person.Age}");
            return View(person);
        }
    }
}

Здесь в post-методе Create, если свойству Name передана строка "admin", то для этого свойства добавляется дополнительная ошибка валидации. То есть с точки зрения атрибутов валидации для свойства Name строка "admin" - корректное значение, а форма благополучно отправится методу контроллера. Но благодаря проверке на сервере подобное значение все равно не пройдет валидацию, :

валидация свойств модели и вывод ошибок с помощью ValidationSummaryTagHelper в ASP.NET Core MVC и C#

Ошибки уровня модели

Теперь изменим определение хелпера, чтобы он отображал только ошибки уровня модели:

@model MvcApp.Models.Person
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers

<form method="post">
    <div asp-validation-summary="ModelOnly"></div>
        <p>
            <label asp-for="Name">Name</label><br />
            <input type="text" asp-for="Name" />
            <span asp-validation-for="Name"  />
        </p>
        <p>
            <label asp-for="Email">Email</label><br />
            <input type="text" asp-for="Email" />
            <span asp-validation-for="Email"  />
        </p>
        <p>
            <label asp-for="Age">Age</label><br />
            <input asp-for="Age" />
            <span asp-validation-for="Age" />
        </p>
        <p>
            <input type="submit" value="Send"  />
        </p>
</form>

<script src="https://ajax.aspnetcdn.com/ajax/jQuery/jquery-3.5.1.min.js"></script>
<script src="https://ajax.aspnetcdn.com/ajax/jquery.validate/1.17.0/jquery.validate.min.js"></script>
<script src="https://ajax.aspnetcdn.com/ajax/jquery.validation.unobtrusive/3.2.10/jquery.validate.unobtrusive.min.js"></script>

А в контроллере в методе, который получает данную форму, добавим дополнительную проверку данных:

using Microsoft.AspNetCore.Mvc;
using MvcApp.Models;  // пространство имен класса Person

namespace MvcApp.Controllers
{
    public class HomeController : Controller
    {
        public IActionResult Create() => View();

        [HttpPost]
        public IActionResult Create(Person person)
        {
            if (person.Name == person.Email)
                ModelState.AddModelError("", "Имя и электронный адрес не должны совпадать.");
            if (ModelState.IsValid)
                return Content($"{person.Name} - {person.Age}");
            return View(person);
        }
    }
}

Здесь в post-методе Create, если свойства Name и Email модели Person имеют одинаковые значение, то добавляется ошибка валидации:

ModelState.AddModelError("", "Имя и электронный адрес не должны совпадать.");

Пустая строка, передаваемая первому параметру метода, указывает, что данная ошибка относится ко всей модели в целом, а не к отдельному свойству. То есть даже если пользователь ввел в форму корректные значения для отдельных свойств и форма была успешна отправлена, но при этом значения свойств Name и Email совпадают, то модель в итоге не пройдет проверку и возвратиться пользователю.

валидация модели и вывод ошибок с помощью ValidationSummaryTagHelper в ASP.NET Core MVC и C#

Стилизация сообщений об ошибках

Когда происходит валидация, то при отображении ошибок соответствующим полям присваиваются определенные классы css:

  • для блока ошибок, который генерируется хелпером ValidationSummaryTagHelper, при наличии ошибок устанавливается класс validation-summary-errors. Если ошибок нет, то данный блок не отображается

  • для элемента <span>, который отображает ошибку для каждого отдельного поля и который генерируется хелпером ValidationTagHelper, при наличии ошибок устанавливается класс field-validation-error. Если ошибок нет, то данный элемент имеет класс field-validation-valid

  • для поля ввода при наличии ошибок устанавливается класс input-validation-error. Если ошибок нет, то устанавливается класс valid

Используя эти классы, мы можем настроить отображение сообщений. Например, изменим представление следующим образом:

@model MvcApp.Models.Person
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers

<style>
.field-validation-error {
    color: #b94a48;
}
 
input.input-validation-error {
    border: 1px solid #b94a48;
}
input.valid {
    border: 1px solid #16a085;
}

.validation-summary-errors {
    color: #b94a48;
}
</style>
<form method="post">
    <div asp-validation-summary="ModelOnly"></div>
        <p>
            <label asp-for="Name">Name</label><br />
            <input type="text" asp-for="Name" />
            <span asp-validation-for="Name"  />
        </p>
        <p>
            <label asp-for="Email">Email</label><br />
            <input type="text" asp-for="Email" />
            <span asp-validation-for="Email"  />
        </p>
        <p>
            <label asp-for="Age">Age</label><br />
            <input asp-for="Age" />
            <span asp-validation-for="Age" />
        </p>
        <p>
            <input type="submit" value="Send"  />
        </p>
</form>

<script src="https://ajax.aspnetcdn.com/ajax/jQuery/jquery-3.5.1.min.js"></script>
<script src="https://ajax.aspnetcdn.com/ajax/jquery.validate/1.17.0/jquery.validate.min.js"></script>
<script src="https://ajax.aspnetcdn.com/ajax/jquery.validation.unobtrusive/3.2.10/jquery.validate.unobtrusive.min.js"></script>
Стилизация ошибок валидации в ASP.NET Core MVC и C#
Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850