Кастомная валидации

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

Встроенные атрибуты валидации покрывают довольно много стандартных сценариев валидации, но тем не менее из функционала может оказаться недостаточно. И в этом случае мы можем создать свой атрибут валидации со своей логикой. Для этого создадим следующий проект:

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

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

using System.ComponentModel.DataAnnotations;

public class PersonNameValidator : ValidationAttribute
{
    string[] names;
    public PersonNameValidator(string[] names)
    {
        this.names = names;
    }
    protected override ValidationResult? IsValid(object? value, ValidationContext validationContext)
    {
        if (names.Contains(value?.ToString()))
        {
            return new ValidationResult("Некорректное имя!");
        }
        return ValidationResult.Success;
    }
}

Класс атрибута валидации должен быть унаследован от класса ValidationAttribute. Здесь класс атрибута валидации принимает массив строк, который представляют запрещенные имена.

Для валидации в классе атрибута надо переопределить метод IsValid(), унаследованный от базового класса ValidationAttribute. Есть две версии этого метода. В данном случае переопределяем версию, которая получает два параметра - value (валидируемое значение) и ValidationContext (контекст валидации). Метод возвращает результат валидации в виде объекта ValidationResult

Мы будем валидировать имя пользователя, то есть строку, поэтому параметр value будет представлять строку. И если в массиве запрещенных имен есть такая строка, то возвращаем ValidationResult, в конструктор которого передается сообщение об ошибке:

if (names.Contains(value?.ToString()))
{
    return new ValidationResult("Некорректное имя!");
}

Если имя корректно, то возвращаем значение ValidationResult.Success, которое будет означать, что валидация прошла успешно.

Применим этот атрибут, для этого определим следующий класс Person:

using System.ComponentModel.DataAnnotations;

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

Здесь применяем наш атрибут PersonNameValidator к свойству Name. А в качестве набора запрещенных имен для теста передаем ему массив с одной строкой "admin".

Пусть компонент 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 пусть используем класс Person:

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

<EditForm Model="@person" OnValidSubmit="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();

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

И если мы введем в поле имени строку "admin", то мы увидим ошибку, которую мы передаем через ValidationResult:

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