Валидация данных в C# (.NET): библиотеки, атрибуты и FluentValidation

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

Валидация данных в C# (.NET): полное руководство

Валидация данных — один из ключевых аспектов разработки надёжных и безопасных приложений на C#. Она позволяет гарантировать, что входные данные соответствуют ожидаемому формату, диапазонам значений и бизнес-правилам. В экосистеме .NET существует несколько мощных инструментов для валидации: от встроенных атрибутов System.ComponentModel.DataAnnotations до гибкой библиотеки FluentValidation. В этой статье мы подробно разберём оба подхода с примерами кода.

1. Встроенная валидация через DataAnnotations

Пространство имён System.ComponentModel.DataAnnotations предоставляет набор атрибутов, которые можно применять к свойствам классов моделей. Это самый простой и быстрый способ валидации, особенно в ASP.NET Core MVC и Blazor.

Основные атрибуты:

  • [Required] — значение не может быть null или пустым.
  • [StringLength(max)] — ограничение длины строки.
  • [Range(min, max)] — проверка числовых диапазонов.
  • [RegularExpression(pattern)] — проверка по регулярному выражению.
  • [EmailAddress] — валидация email.
  • [Compare("OtherProperty")] — сравнение двух свойств (например, пароль и подтверждение).

Пример модели с атрибутами:

public class UserRegistrationDto
{
    [Required(ErrorMessage = "Имя обязательно")]
    [StringLength(50, MinimumLength = 2, ErrorMessage = "Имя должно содержать от 2 до 50 символов")]
    public string FirstName { get; set; }

    [Required(ErrorMessage = "Email обязателен")]
    [EmailAddress(ErrorMessage = "Некорректный формат email")]
    public string Email { get; set; }

    [Required]
    [Range(18, 120, ErrorMessage = "Возраст должен быть от 18 до 120")]
    public int Age { get; set; }

    [Required]
    [DataType(DataType.Password)]
    public string Password { get; set; }

    [Compare("Password", ErrorMessage = "Пароли не совпадают")]
    public string ConfirmPassword { get; set; }
}

Ручная проверка модели:

public static bool ValidateUser(UserRegistrationDto user, out List<ValidationResult> errors)
{
    var context = new ValidationContext(user);
    errors = new List<ValidationResult>();
    return Validator.TryValidateObject(user, context, errors, validateAllProperties: true);
}

// Использование:
var user = new UserRegistrationDto { FirstName = "A", Email = "invalid", Age = 15 };
if (!ValidateUser(user, out var errors))
{
    foreach (var error in errors)
        Console.WriteLine(error.ErrorMessage);
}

2. FluentValidation — продвинутая валидация

Библиотека FluentValidation (NuGet: FluentValidation.AspNetCore) предлагает более гибкий и читаемый способ описания правил валидации через fluent-интерфейс. Она идеально подходит для сложных сценариев: условная валидация, кастомные сообщения, цепочки правил и интеграция с DI-контейнерами.

Установка через NuGet:

dotnet add package FluentValidation.AspNetCore

Пример валидатора:

using FluentValidation;

public class UserValidator : AbstractValidator<UserRegistrationDto>
{
    public UserValidator()
    {
        RuleFor(u => u.FirstName)
            .NotEmpty().WithMessage("Имя не может быть пустым")
            .Length(2, 50).WithMessage("Имя должно содержать от 2 до 50 символов");

        RuleFor(u => u.Email)
            .NotEmpty().WithMessage("Email обязателен")
            .EmailAddress().WithMessage("Некорректный формат email");

        RuleFor(u => u.Age)
            .InclusiveBetween(18, 120).WithMessage("Возраст должен быть от 18 до 120");

        RuleFor(u => u.Password)
            .NotEmpty()
            .MinimumLength(6).WithMessage("Пароль должен содержать минимум 6 символов");

        RuleFor(u => u.ConfirmPassword)
            .Equal(u => u.Password).WithMessage("Пароли не совпадают");

        // Условная валидация: если возраст меньше 21, требуется согласие родителей
        RuleFor(u => u.ParentalConsent)
            .Equal(true).WithMessage("Требуется согласие родителей")
            .When(u => u.Age < 21);
    }
}

Использование валидатора:

var validator = new UserValidator();
var user = new UserRegistrationDto { FirstName = "Иван", Email = "ivan@test.com", Age = 17 };

var result = validator.Validate(user);
if (!result.IsValid)
{
    foreach (var failure in result.Errors)
        Console.WriteLine($"Свойство {failure.PropertyName}:                    

Рекомендаций