Модели в ASP.NET Core MVC. Валидация на стороне клиента

До этого момента мы использовали механизмы валидации модели на стороне сервера. То есть, прежде, чем пройти валидацию, модель отправлялась на сервер и уже на сервере запускался механизм валидации. Вместе с этим, в ASP.NET Core MVC предусмотрен и другой подход к валидации данных — валидация на стороне клиента. Валидация на стороне клиента позволяет избежать лишних запросов к серверу и использует специальные библиотеки JavaScript, разработанные Microsoft на основе jQuery.

Необходимые библиотеки JavaScript

Для того, чтобы можно было использовать валидацию на стороне клиента, мы должны подключить в _Layout.cshtml или в определенное представление следующие скрипты JavaScript:

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-validate/1.19.3/jquery.validate.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-validation-unobtrusive/3.2.12/jquery.validate.unobtrusive.js"></script>

Первый скрипт — jquery, от которого зависят другие скрипты. Второй — плагин валидации Jquery Validate. Третий — библиотека jQuery Unobtrusive Validation дополняет скрипт валидации, добавляя поддержку data-атрибутов. Для подключения скриптов нам не обязательно использовать CDN. Скрипты можно загрузить локально в проект и подключить.

Пример валидации на стороне клиента

Рассмотрим использование валидации на стороне клиента на примере. Создадим новое приложение ASP.NET Core MVC и добавим в файл Views/Home/Index.cshtml скрипты

@{
    ViewData["Title"] = "Home Page";
}

<div class="text-center">
    <h1 class="display-4">Welcome</h1>
    <p>Learn about <a href="https://docs.microsoft.com/aspnet/core">building Web apps with ASP.NET Core</a>.</p>
</div>

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-validate/1.19.3/jquery.validate.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-validation-unobtrusive/3.2.12/jquery.validate.unobtrusive.js"></script>

В этот же файл добавим веб-форму:

<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="Age">Age</label><br />
            <input asp-for="Age" />
            <span asp-validation-for="Age" />
        </p>
        <p>
            <label asp-for="Email">Email</label><br />
            <input asp-for="Email" />
            <span asp-validation-for="Email" />
        </p>
        <p>
            <input type="submit" value="Send" />
        </p>
    </div>
</form>

Здесь можно увидеть, что в html-тэгах формы присутствуют нове для нас атрибуты типа asp-for, asp-validation-for. Это так называемые tag-хэлперы, которые, наравне с html-хэлперами (о которых мы уже знаем) могут использоваться для генерации html-разметки. В данном случае, нас интересует tag-хэлпер asp-validation-for. Атрибуту asp-validation-for передается название свойства модели, для которого будет выводиться сообщение, если свойство не проходит валидацию.

Теперь добавим в папку Models модель которая будет использоваться для демонстрации валидации:

public class Person
{
    [Required(ErrorMessage ="Поле Name обязательно к заполнению")]
    public string Name { get; set; }
    [EmailAddress]
    public string Email { get; set; }
    [Range(1, 100, ErrorMessage = "Возраст должен находится в пределах от 1 до 100 лет")]
    public int Age { get; set; }
}

Здесь мы сразу применили к свойствам модели атрибуты валидации и определили в этих атрибутах текст ошибок, которые будут выводиться пользователю. Добавим тип модели в представление Views/Home/Index.cshtml. Вот так должно теперь выглядеть наше представление полностью:

@model Person
@{
    ViewData["Title"] = "Home Page";
}

<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="Age">Age</label><br />
            <input asp-for="Age" />
            <span asp-validation-for="Age" />
        </p>
        <p>
            <label asp-for="Email">Email</label><br />
            <input asp-for="Email" />
            <span asp-validation-for="Email" />
        </p>
        <p>
            <input type="submit" value="Send" />
        </p>
    </div>
</form>


<div class="text-center">
    <h1 class="display-4">Welcome</h1>
    <p>Learn about <a href="https://docs.microsoft.com/aspnet/core">building Web apps with ASP.NET Core</a>.</p>
</div>

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-validate/1.19.3/jquery.validate.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-validation-unobtrusive/3.2.12/jquery.validate.unobtrusive.js"></script>

Теперь перейдем к контроллеру HomeController и создадим новое действие:

[HttpPost]
public IActionResult Index(Person person)
{
    return Ok(person);
}

Теперь можно запустить приложение и попробовать заполнить форму. Как только мы заполняем очередное поле формы и переходим к следующему, запускается валидация на стороне клиента и, если обнаружена ошибка валидации, то она сразу выводится пользователю:

Если же форма заполнена корректно, то клик по кнопке «Send» отправит форму на сервер, сработает наше действие Index() и мы увидим JSON-объект:

Сама же веб-форма в приложении будет иметь следующую html-разметку:

<form method="post">
    <div>
        <p>
            <label for="Name">Name</label><br />
            <input type="text" data-val="true" data-val-required="Поле Name обязательно к заполнению" id="Name" name="Name" value="" />
            <span class="field-validation-valid" data-valmsg-for="Name" data-valmsg-replace="true" />
        </p>
        <p>
            <label for="Age">Age</label><br />
            <input type="number" data-val="true" data-val-range="Возраст должен находится в пределах от 1 до 100 лет" data-val-range-max="100" data-val-range-min="1" data-val-required="The Age field is required." id="Age" name="Age" value="" /><input name="__Invariant" type="hidden" value="Age" />
            <span class="field-validation-valid" data-valmsg-for="Age" data-valmsg-replace="true" />
        </p>
        <p>
            <label for="Email">Email</label><br />
            <input type="email" data-val="true" data-val-email="The Email field is not a valid e-mail address." data-val-required="The Email field is required." id="Email" name="Email" value="" />
            <span class="field-validation-valid" data-valmsg-for="Email" data-valmsg-replace="true" />
        </p>
        <p>
            <input type="submit" value="Send" />
        </p>
    </div>
<input name="__RequestVerificationToken" type="hidden" value="CfDJ8F-cW7GXuzBHuhFhRkcFZJFM1We9TlKqep3_cmJCa84k3opiwDjoP6HygdEzc6glv3ERRwNDvAXOZPhbaP1Byr8KHV8PQvusJYICBkcnxCy2vFx_wFWvGIu33SPklhTu__FgSyPD15QEXo0tlqplAjw" /></form>

Про различные tag-хэлперы ещё будет отдельный раздел, а пока перейдем к следующему моменту использования валидации модели на стороне клиента.

Атрибут Remote

Подключение в проект скриптов для валидации на стороне клиента также дает нам возможность использования ещё одного атрибута валидации модели — Remote. Атрибут Remote располагается в пространстве имен Microsoft.AspNetCore.Mvc Для валидации свойства этот атрибут выполняет запрос на сервер к определенному методу контроллера. И если требуемый метод контроллера вернет значение false, то валидация не пройдена. Например, напишем следующий метод контроллера:

public IActionResult CheckMail(string email)
{
    if (email == "admin@mail.ru")
        return Json(false);
    return Json(true);
}

Этот метод возвращает в JSON либо true, либо false. Стоит отметить, что имя параметра метода должно совпадать с именем поля формы, которое должно отправляться на сервер для валидации (без учёта регистра).

Теперь добавим атрибут валидации для свойства Email модели:

[EmailAddress]
[Remote(action: "CheckMail", controller:"Home", ErrorMessage ="Ошибка: такой email нельзя использовать")]
public string Email { get; set; }

В параметрах атрибута мы указали имя метода, имя контроллера в котором находится метод и текст ошибки. Теперь, при попытке отправить на сервер форму в которой будет задан адрес электронной почты admin@mail.ru мы получим следующую ошибку:

Итого

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

Подписаться
Уведомить о
guest
0 Комментарий
Старые
Новые Популярные
Межтекстовые Отзывы
Посмотреть все комментарии