Программная валидация

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

Для программной валидации данных формы можно использовать объект EditContext и его функционал. В частности, с помошью его метода Validate() можно проверять валидность введенных данных - если они корректны, то метод возвращает true. Где мы можем это использовать? Компонент EditForm предоставляет три метода для отправки данных формы

  • OnValidSubmit срабатывает, если нет ошибок валидации

  • OnInvalidSubmit срабатывает, если есть ошибки валидации

  • OnSubmit срабатывает вне зависимости от наличия ошибок валидации

Если для отправки формы применяется метод OnSubmit, то мы можем использовать метод EditContext.Validate() для проверки на валидность перед отправкой.

Пусть у нас в проекте есть класс Person, который представляет данные, и два компонента - App и Home:

Валидация в компонентах Blazor и ASP.NET

Класс Person будет представлять используемую модель данных:

using System.ComponentModel.DataAnnotations;

public class Person
{
    [Required]
    [StringLength(20, MinimumLength = 2)]
    public string Name { get; set; } = "";
    [Required]
    [Range(1, 110)]
    public int Age { get; set; }
}

Пусть компонент App представляет корневой компонент и просто выводит на страницу компонент Home:

@page "/"

<!DOCTYPE html>
<html>
<head>
    <title>METANIT.COM</title>
    <meta charset="utf-8" />
</head>
<body>
    <Home />
    <script src="_framework/blazor.web.js"></script>
</body>
</html>

А в компоненте Home определим код формы и программной проверки на валидность:

@using Microsoft.AspNetCore.Components.Web
@using Microsoft.AspNetCore.Components.Forms
@rendermode RenderMode.InteractiveServer

<EditForm EditContext="editContext" OnSubmit="Submit">
    <DataAnnotationsValidator />
    <ValidationSummary />
    <p>
        Name:<br />
        <InputText id="name" @bind-Value="person.Name" />
    </p>
    <p>
        Age:<br />
        <InputNumber id="age" @bind-Value="person.Age" />
    </p>
    <button type="submit">Submit</button>
</EditForm>
<h3>@message</h3>

@code {
    string message = "";
    Person person = new();
    EditContext? editContext;

    protected override void OnInitialized()
    {
        editContext = new(person);
    }

    void Submit()
    {
        if (editContext != null && editContext.Validate())
            message = $"Name: {person.Name}; Age: {person.Age}";
        else
            message = "Data Invalid";
    }
}

Для установки объекта EditContext у класса EditForm применяется одноименное свойство

<EditForm EditContext="editContext"

Здесь объект EditContext создается в методе OnInitialized(), который вызывается при инициализации компонента:

Person person = new();
EditContext? editContext;

protected override void OnInitialized()
{
    editContext = new(person);
}

В методе Submit(), который вызывается по нажатию на кнопку, проверяем валидность данных, вызывая у EditContext метод Validate()

void Submit()
{
    if (editContext!=null && editContext.Validate())
        message = $"Name: {person.Name}; Age: {person.Age}";
Проверка валидности данных в EditForm в компонентах Blazor на C#

OnValidSubmit

Если нам надо, чтобы нажатие на кнопку не срабатывало, если данные не корректны, то проще всего использовать событие OnValidSubmit:

@using Microsoft.AspNetCore.Components.Web
@using Microsoft.AspNetCore.Components.Forms
@rendermode RenderMode.InteractiveServer

<EditForm EditContext="editContext" OnValidSubmit="ValidSubmit">
    <DataAnnotationsValidator />
    <ValidationSummary />
    <p>
        Name:<br />
        <InputText id="name" @bind-Value="person.Name" />
    </p>
    <p>
        Age:<br />
        <InputNumber id="age" @bind-Value="person.Age" />
    </p>
    <button type="submit">Submit</button>
</EditForm>
<h3>@message</h3>

@code {
    string message = "";
    Person person = new();

    void ValidSubmit()
    {
        message = $"Name: {person.Name}; Age: {person.Age}";
    }
}

Теперь, пока не будут введены корректные данные, метод ValidSubmit выполняться не будет.

Отслеживание изменения состояния валидации

Класс EditContext предоставляет событие OnValidationStateChanged, которое позволяет отслеживать состояние валидации. Данное событие срабатывает при каждом изменении значений в полях ввода. Соответственно здесь мы можем проверить различные данные, связанные с валидацией, или выполнить какие-то действия, например, добавить кастомную логику валидации. Рассмотрим небольшой пример. Пусть в компоненте Home будет прописан следующий код:

@using Microsoft.AspNetCore.Components.Web
@using Microsoft.AspNetCore.Components.Forms
@rendermode RenderMode.InteractiveServer
@implements IDisposable

<EditForm EditContext="editContext" OnSubmit="Submit">
    <DataAnnotationsValidator />
    <ValidationSummary />
    <p>
        Name:<br />
        <InputText id="name" @bind-Value="person.Name" />
    </p>
    <p>
        Age:<br />
        <InputNumber id="age" @bind-Value="person.Age" />
    </p>
    <button type="submit">Submit</button>
</EditForm>
<h3>@message</h3>

@code {
    string message = "";
    Person person = new();
    EditContext? editContext;
    ValidationMessageStore? messageStore;   // хранилище сообщений об ошибках

    protected override void OnInitialized()
    {
        editContext = new(person);
        messageStore = new(editContext);    // связываем хранилище сообщений с контекстом EditContext
        editContext.OnValidationStateChanged += HandleValidationRequested;
    }
    void HandleValidationRequested(object? sender, ValidationStateChangedEventArgs args)
    {
        messageStore?.Clear();  // удаляем ранее добавленные сообщения
                                // если имя - admin, добавляем сообщение обошибке
        if (person.Name == "admin")
            messageStore?.Add(() => person.Name!, "Invalid name");
    }
    public void Dispose()
    {
        if (editContext != null)
            editContext.OnValidationStateChanged -= HandleValidationRequested;
    }
    void Submit()
    {
        if (editContext != null && editContext.Validate())
            message = $"Name: {person.Name}; Age: {person.Age}";
        else
            message = "Data Invalid";
    }
}

В данном случае будем считать, что имя "admin" - недействительное. И нам надо как-то уведомить об этом пользователя. Для этого определяем хранилище сообщений об ошибках - объект ValidationMessageStore:

ValidationMessageStore? messageStore;

Конструктор этого класса принимает контекст EditContext, с которым ассоциируется это хранилище сообшений. И в методе OnInitialized() создаем это хранилище:

messageStore = new(editContext);

Чтобы отслеживать изменение состояния валидации, также в методе OnInitialized() подписываемся на событие OnValidationStateChanged

editContext.OnValidationStateChanged += HandleValidationRequested;

В методе-обработчике HandleValidationRequested добавляем в хранилище сообщений одно сообщение, если введенное имя равно "admin":

void HandleValidationRequested(object? sender, ValidationStateChangedEventArgs args)
{
    messageStore?.Clear();  // удаляем ранее добавленные сообщения
    if (person.Name == "admin") 
        messageStore?.Add(() => person.Name!, "Invalid name");
}

Прежде чем добавить сообщения, мы очищаем хранилище сообшений с помошью метода Clear(). А для добавления сообщения применяется метод Add(). Первый параметр метода Add() - делегат, который определяет свойство валидируемого объекта (в данном случае свойство Name). Второй параметр - собственно сообщение об ошибке в виде строки.

И как и в случае с любыми другими событиями, нам надо отписаться от события OnValidationStateChanged в методе Dispose():

@implements IDisposable  // реализуем интерфейс IDisposable

public void Dispose()
{
    if(editContext != null)
        editContext.OnValidationStateChanged -= HandleValidationRequested;
}

И теперь имя "admin" будет считаться недействительным:

Кастомная валидация в компонентах Blazor на C#
Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850