← Предыдущая часть

*При написании статьи использовались .NET 8/C# 12.

Это очередная статья по обзору библиотеки FluentValidation на русском языке. Источником информации является официальная документация. Не могу назвать это уроком или полноценным переводом, решил назвать это обзорами. Здесь иногда можно увидеть то, чего не описано в официальной документации, а также более подробные примеры.

FluentValidation — это .NET библиотека для описания строго-типизированных правил валидации данных в виде текучего синтаксиса, и последующего их применения. Библиотека достаточно гибкая, можно строить поддерживаемые валидации любой сложности.

В этой части рассмотрим следующие валидаторы (5):

  • Length — длина строки в указанном диапазоне либо точная.

  • MaximumLength — максимальная длина строки.

  • MinimumLength — минимальная длина строки.

  • LessThan — меньше чем значение, тип которого реализует интерфейс IComparable.

  • LessThanOrEqualTo — меньше или равно чем значение, тип которого реализует интерфейс IComparable.

Список всех встроенных валидаторов (22):

Содержание может помочь удобно ориентироваться в статье, из-за большого объёма материала. Статья не на один раз, к ней можно и нужно периодически возвращаться.

Важно! Примеры кода ниже, как и описания валидаторов, являются самодостаточными, достаточно создать консольное приложение на .NET 8/C# 12 и подключить туда NuGet пакет FluentValidation 11.9.2 версии и просто копи-пастить код целиком в Program.cs для самостоятельной проверки.

Содержание:

Валидатор Length.

К списку валидаторов

Описание:

Гарантирует, что длина строки (тип string) находится в пределах диапазона двух целочисленных значений включительно (минимальное количество символов и максимальное количество символов) либо точно равна указанному целочисленному значению (конкретное количество символов).

Исходный код валидатора.

Примеры кода:

Проверим, что длина строки находится в пределах диапазона двух целочисленных значений (минимальное количество символов и максимальное количество символов).

// Сигнатура перегруженного метода валидатора
public static IRuleBuilderOptions<T, string> Length<T>(
    this IRuleBuilder<T, string> ruleBuilder,
    int min,
    int max
)
// Пример кода
using FluentValidation;
using FluentValidation.Results;

// Создаём модель и заполняем данными
Request request = new()
{
    Input = "someinput", // Длина 9 символов
};
// Создаём валидатор
RequestValidator validator = new();

// Валидируем модель, получаем результат
ValidationResult validationResult = validator.Validate(request);

// Валидация успешно пройдена?
if (validationResult.IsValid)
    Console.WriteLine("Валидация пройдена успешно!");
else
    // Выводим ошибки на консоль, разделяя символом |
    Console.WriteLine(validationResult.ToString("|"));

// Не даём закрыться консоли
Console.ReadLine();

/// <summary>
/// Модель для валидатора <see cref="RequestValidator"/>
/// </summary>
internal record Request
{
    /// <summary>
    /// Валидируемое свойство
    /// </summary>
    public required string Input { get; init; }
}

/// <summary>
/// Валидатор для модели <see cref="Request"/>
/// </summary>
internal class RequestValidator : AbstractValidator<Request>
{
    public RequestValidator()
    {
        // Длина строки должна быть от 8 до 10 символов включительно
        RuleFor(request => request.Input).Length(8, 10);
    }
}

Проверим, что длина строки находится в пределах диапазона двух целочисленных значений свойств (минимальное количество символов и максимальное количество символов):

// Сигнатура перегруженного метода валидатора
public static IRuleBuilderOptions<T, string> Length<T>(
    this IRuleBuilder<T, string> ruleBuilder,
    Func<T, int> min,
    Func<T, int> max
)
// Пример кода
using FluentValidation;
using FluentValidation.Results;

// Создаём модель и заполняем данными
Request request = new()
{
    LengthFrom = 8, // Свойство используется в валидаторе (Длина "От")
    Input = "someinput", // Длина 9 символов
    LengthTo = 10, // Свойство используется в валидаторе (Длина "До")
};
// Создаём валидатор
RequestValidator validator = new();

// Валидируем модель, получаем результат
ValidationResult validationResult = validator.Validate(request);

// Валидация успешно пройдена?
if (validationResult.IsValid)
    Console.WriteLine("Валидация пройдена успешно!");
else
    // Выводим ошибки на консоль, разделяя символом |
    Console.WriteLine(validationResult.ToString("|"));

Console.ReadLine();

/// <summary>
/// Модель для валидатора <see cref="RequestValidator"/>
/// </summary>
internal record Request
{
    /// <summary>
    /// Длина "От"
    /// </summary>
    public required int LengthFrom { get; init; }
    /// <summary>
    /// Валидируемое свойство
    /// </summary>
    public required string Input { get; init; }
    /// <summary>
    /// Длина "До"
    /// </summary>
    public required int LengthTo { get; init; }
}

/// <summary>
/// Валидатор для модели <see cref="Request"/>
/// </summary>
internal class RequestValidator : AbstractValidator<Request>
{
    public RequestValidator()
    {
        // Длина строки должна быть от 8 до 10 символов включительно
        RuleFor(request => request.Input)
            .Length(request => request.LengthFrom, request => request.LengthTo);
    }
}

Проверим, что длина строки равна целочисленному значению (конкретное количество символов):

// Сигнатура перегруженного метода валидатора
public static IRuleBuilderOptions<T, string> Length<T>(
    this IRuleBuilder<T, string> ruleBuilder,
    int exactLength
)
// Пример кода
using FluentValidation;
using FluentValidation.Results;

// Создаём модель и заполняем данными
Request request = new()
{
    Input = "someinput", // Длина 9 символов
};
// Создаём валидатор
RequestValidator validator = new();

// Валидируем модель, получаем результат
ValidationResult validationResult = validator.Validate(request);

// Валидация успешно пройдена?
if (validationResult.IsValid)
    Console.WriteLine("Валидация пройдена успешно!");
else
    // Выводим ошибки на консоль, разделяя символом |
    Console.WriteLine(validationResult.ToString("|"));

Console.ReadLine();

/// <summary>
/// Модель для валидатора <see cref="RequestValidator"/>
/// </summary>
internal record Request
{
    /// <summary>
    /// Валидируемое свойство
    /// </summary>
    public required string Input { get; init; }
}

/// <summary>
/// Валидатор для модели <see cref="Request"/>
/// </summary>
internal class RequestValidator : AbstractValidator<Request>
{
    public RequestValidator()
    {
        // Длина строки должна быть равна 9-ти символам
        RuleFor(request => request.Input).Length(9);
    }
}

Проверим, что длина строки равна целочисленному значению свойства (конкретное количество символов):

// Сигнатура перегруженного метода валидатора
public static IRuleBuilderOptions<T, string> Length<T>(
    this IRuleBuilder<T, string> ruleBuilder,
    Func<T, int> exactLength
)
// Пример кода
using FluentValidation;
using FluentValidation.Results;

// Создаём модель и заполняем данными
Request request = new()
{
    ExactlyLength = 9, // Свойство используется в валидаторе (Точная длина)
    Input = "someinput", // Длина 9 символов
};
// Создаём валидатор
RequestValidator validator = new();

// Валидируем модель, получаем результат
ValidationResult validationResult = validator.Validate(request);

// Валидация успешно пройдена?
if (validationResult.IsValid)
    Console.WriteLine("Валидация пройдена успешно!");
else
    // Выводим ошибки на консоль, разделяя символом |
    Console.WriteLine(validationResult.ToString("|"));

Console.ReadLine();

/// <summary>
/// Модель для валидатора <see cref="RequestValidator"/>
/// </summary>
internal record Request
{
    /// <summary>
    /// Валидируемое свойство
    /// </summary>
    public required string Input { get; init; }
    /// <summary>
    /// Точная длина
    /// </summary>
    public required int ExactlyLength { get; init; }
}

/// <summary>
/// Валидатор для модели <see cref="Request"/>
/// </summary>
internal class RequestValidator : AbstractValidator<Request>
{
    public RequestValidator()
    {
        // Длина строки должна быть равна 9-ти символам
        RuleFor(request => request.Input)
            .Length(request => request.ExactlyLength);
    }
}

Примеры ошибок:

// Когда указываем диапазон
'Input' должно быть длиной от 8 до 10 символов. Количество введенных символов: 11.
// Когда указываем точное значение
'Input' должно быть длиной 10 символа(ов). Количество введенных символов: 9.

Доступные заполнители:

{PropertyName} — название валидируемого свойства

{PropertyValue} — значение валидируемого свойства

{PropertyPath} — полный путь к свойству

{MinLength} — минимальная длина

{MaxLength} — максимальная длина

{TotalLength} — длина проверяемого строчного значения

Пример кода с заполнителями 1 (диапазон):

using FluentValidation;
using FluentValidation.Results;

// Создаём модель и заполняем данными
Request request = new()
{
    Input = "someinputtt", // Длина 11 символов
};
// Создаём валидатор
RequestValidator validator = new();

// Валидируем модель, получаем результат
ValidationResult validationResult = validator.Validate(request);

// Валидация успешно пройдена?
if (validationResult.IsValid)
    Console.WriteLine("Валидация пройдена успешно!");
else
    // Выводим ошибки на консоль, разделяя символом |
    Console.WriteLine(validationResult.ToString("|"));

Console.ReadLine();

/// <summary>
/// Модель для валидатора <see cref="RequestValidator"/>
/// </summary>
internal record Request
{
    /// <summary>
    /// Валидируемое свойство
    /// </summary>
    public required string Input { get; init; }
}

/// <summary>
/// Валидатор для модели <see cref="Request"/>
/// </summary>
internal class RequestValidator : AbstractValidator<Request>
{
    public RequestValidator()
    {
        // Длина строки должна быть от 8 до 10 символов включительно
        RuleFor(request => request.Input)
            .Length(8, 10)
                .WithMessage("""
                             PropertyName: {PropertyName}
                             PropertyValue: {PropertyValue}
                             PropertyPath: {PropertyPath}
                             MinLength: {MinLength}
                             MaxLength: {MaxLength}
                             TotalLength: {TotalLength}
                             """);
    }
}

Пример ошибки с заполнителями 1 (диапазон):

PropertyName: Input
PropertyValue: someinputtt
PropertyPath: Input
MinLength: 8
MaxLength: 10
TotalLength: 11

Пример кода с заполнителями 2 (точное значение):

using FluentValidation;
using FluentValidation.Results;

// Создаём модель и заполняем данными
Request request = new()
{
    Input = "someinputtt", // Длина 11 символов
};
// Создаём валидатор
RequestValidator validator = new();

// Валидируем модель, получаем результат
ValidationResult validationResult = validator.Validate(request);

// Валидация успешно пройдена?
if (validationResult.IsValid)
    Console.WriteLine("Валидация пройдена успешно!");
else
    // Выводим ошибки на консоль, разделяя символом |
    Console.WriteLine(validationResult.ToString("|"));

Console.ReadLine();

/// <summary>
/// Модель для валидатора <see cref="RequestValidator"/>
/// </summary>
internal record Request
{
    /// <summary>
    /// Валидируемое свойство
    /// </summary>
    public required string Input { get; init; }
}

/// <summary>
/// Валидатор для модели <see cref="Request"/>
/// </summary>
internal class RequestValidator : AbstractValidator<Request>
{
    public RequestValidator()
    {
        // Длина строки должна быть равна 8-ми символам
        RuleFor(request => request.Input)
            .Length(8)
                .WithMessage("""
                             PropertyName: {PropertyName}
                             PropertyValue: {PropertyValue}
                             PropertyPath: {PropertyPath}
                             MinLength: {MinLength}
                             MaxLength: {MaxLength}
                             TotalLength: {TotalLength}
                             """);
    }
}

Пример ошибки с заполнителями 2 (точное значение):

PropertyName: Input
PropertyValue: someinputtt
PropertyPath: Input
MinLength: 8
MaxLength: 8
TotalLength: 11

Валидатор MaximumLength.

К списку валидаторов

Описание:

Гарантирует, что длина строки (тип string) не больше, чем указанное целочисленное значение (максимальное количество символов).

Исходный код валидатора.

Пример кода:

// Сигнатура метода валидатора
public static IRuleBuilderOptions<T, string> MaximumLength<T>(
    this IRuleBuilder<T, string> ruleBuilder,
    int maximumLength
)
// Пример кода
using FluentValidation;
using FluentValidation.Results;

// Создаём модель и заполняем данными
Request request = new()
{
    Input = "someinput", // Длина 9 символов
};
// Создаём валидатор
RequestValidator validator = new();

// Валидируем модель, получаем результат
ValidationResult validationResult = validator.Validate(request);

// Валидация успешно пройдена?
if (validationResult.IsValid)
    Console.WriteLine("Валидация пройдена успешно!");
else
    // Выводим ошибки на консоль, разделяя символом |
    Console.WriteLine(validationResult.ToString("|"));

Console.ReadLine();

/// <summary>
/// Модель для валидатора <see cref="RequestValidator"/>
/// </summary>
internal record Request
{
    /// <summary>
    /// Валидируемое свойство
    /// </summary>
    public required string Input { get; init; }
}

/// <summary>
/// Валидатор для модели <see cref="Request"/>
/// </summary>
internal class RequestValidator : AbstractValidator<Request>
{
    public RequestValidator()
    {
        // Длина строки должна быть не более 9-ти символов
        RuleFor(request => request.Input).MaximumLength(9);
    }
}

Пример ошибки:

'Input' должно быть длиной не более 9 символов. Количество введенных символов: 10.

Доступные заполнители:

{PropertyName} — название валидируемого свойства

{PropertyValue} — значение валидируемого свойства

{PropertyPath} — полный путь к свойству

{MaxLength} — максимальная длина

{TotalLength} — длина проверяемого строчного значения

Пример кода с заполнителями:

using FluentValidation;
using FluentValidation.Results;

// Создаём модель и заполняем данными
Request request = new()
{
    Input = "someinputе", // Длина 9 символов
};
// Создаём валидатор
RequestValidator validator = new();

// Валидируем модель, получаем результат
ValidationResult validationResult = validator.Validate(request);

// Валидация успешно пройдена?
if (validationResult.IsValid)
    Console.WriteLine("Валидация пройдена успешно!");
else
    // Выводим ошибки на консоль, разделяя символом |
    Console.WriteLine(validationResult.ToString("|"));

Console.ReadLine();

/// <summary>
/// Модель для валидатора <see cref="RequestValidator"/>
/// </summary>
internal record Request
{
    /// <summary>
    /// Валидируемое свойство
    /// </summary>
    public required string Input { get; init; }
}

/// <summary>
/// Валидатор для модели <see cref="Request"/>
/// </summary>
internal class RequestValidator : AbstractValidator<Request>
{
    public RequestValidator()
    {
        // Длина строки должна быть не более 9-ти символов
        RuleFor(request => request.Input)
            .MaximumLength(9)
            .WithMessage("""
                         PropertyName: {PropertyName}
                         PropertyValue: {PropertyValue}
                         PropertyPath: {PropertyPath}
                         MaxLength: {MaxLength}
                         TotalLength: {TotalLength}
                         """);
    }
}

Пример ошибки с заполнителями:

PropertyName: Input
PropertyValue: someinputе
PropertyPath: Input
MaxLength: 9
TotalLength: 10

Валидатор MinimumLength.

К списку валидаторов

Описание:

Гарантирует, что длина строки (тип string) не меньше, чем указанное целочисленное значение (минимальное количество символов).

Исходный код валидатора.

Пример кода:

// Сигнатура метода валидатора
public static IRuleBuilderOptions<T, string> MinimumLength<T>(
    this IRuleBuilder<T, string> ruleBuilder,
    int minimumLength
)
// Пример кода
using FluentValidation;
using FluentValidation.Results;

// Создаём модель и заполняем данными
Request request = new()
{
    Input = "someinput", // Длина 9 символов
};
// Создаём валидатор
RequestValidator validator = new();

// Валидируем модель, получаем результат
ValidationResult validationResult = validator.Validate(request);

// Валидация успешно пройдена?
if (validationResult.IsValid)
    Console.WriteLine("Валидация пройдена успешно!");
else
    // Выводим ошибки на консоль, разделяя символом |
    Console.WriteLine(validationResult.ToString("|"));

Console.ReadLine();

/// <summary>
/// Модель для валидатора <see cref="RequestValidator"/>
/// </summary>
internal record Request
{
    /// <summary>
    /// Валидируемое свойство
    /// </summary>
    public required string Input { get; init; }
}

/// <summary>
/// Валидатор для модели <see cref="Request"/>
/// </summary>
internal class RequestValidator : AbstractValidator<Request>
{
    public RequestValidator()
    {
        // Длина строки должна быть не менее 9-ти символов
        RuleFor(request => request.Input).MinimumLength(9);
    }
}

Пример ошибки:

'Input' должно быть длиной не менее 9 символов. Количество введенных символов: 8.

Доступные заполнители:

{PropertyName} — название валидируемого свойства

{PropertyValue} — значение валидируемого свойства

{PropertyPath} — полный путь к свойству

{MinLength} — минимальная длина

{TotalLength} — длина проверяемого строчного значения

Пример кода с заполнителями:

using FluentValidation;
using FluentValidation.Results;

// Создаём модель и заполняем данными
Request request = new()
{
    Input = "someinpu", // Длина 8 символов
};
// Создаём валидатор
RequestValidator validator = new();

// Валидируем модель, получаем результат
ValidationResult validationResult = validator.Validate(request);

// Валидация успешно пройдена?
if (validationResult.IsValid)
    Console.WriteLine("Валидация пройдена успешно!");
else
    // Выводим ошибки на консоль, разделяя символом |
    Console.WriteLine(validationResult.ToString("|"));

Console.ReadLine();

/// <summary>
/// Модель для валидатора <see cref="RequestValidator"/>
/// </summary>
internal record Request
{
    /// <summary>
    /// Валидируемое свойство
    /// </summary>
    public required string Input { get; init; }
}

/// <summary>
/// Валидатор для модели <see cref="Request"/>
/// </summary>
internal class RequestValidator : AbstractValidator<Request>
{
    public RequestValidator()
    {
        // Длина строки должна быть не менее 9-ти символов
        RuleFor(request => request.Input)
            .MinimumLength(9)
            .WithMessage("""
                         PropertyName: {PropertyName}
                         PropertyValue: {PropertyValue}
                         PropertyPath: {PropertyPath}
                         MinLength: {MinLength}
                         TotalLength: {TotalLength}
                         """);
    }
}

Пример ошибки с заполнителями:

PropertyName: Input
PropertyValue: someinpu
PropertyPath: Input
MinLength: 9
TotalLength: 8

Валидатор LessThan.

К списку валидаторов

Описание:

Гарантирует, что указанное значение, тип которого реализует интерфейс IComparable, будет меньше, чем указанное значение, тип которого также реализует интерфейс IComparable.

Исходный код валидатора.

Примеры кода:

Проверим, что указанное значение меньше указанного значения.

// Сигнатуры перегрузок методов валидатора в примере кода.
// Есть и другие, но их опущу, они связаны с nullable типами.
public static IRuleBuilderOptions<T, TProperty> LessThan<T, TProperty>(
    this IRuleBuilder<T, TProperty> ruleBuilder,
    TProperty valueToCompare
) where TProperty : IComparable<TProperty>, IComparable

public static IRuleBuilderOptions<T, TProperty?> LessThan<T, TProperty>(
    this IRuleBuilder<T, TProperty?> ruleBuilder,
	TProperty valueToCompare
) where TProperty : struct, IComparable<TProperty>, IComparable

using FluentValidation;
using FluentValidation.Results;

// Создаём модель и заполняем данными
Request request = new()
{
    InputInt = 4,
    InputNullableInt = 4,
    InputDateTime = DateTime.Now.AddDays(-5),
};
// Создаём валидатор
RequestValidator validator = new();

// Валидируем модель, получаем результат
ValidationResult validationResult = validator.Validate(request);

// Валидация успешно пройдена?
if (validationResult.IsValid)
    Console.WriteLine("Валидация пройдена успешно!");
else
    // Выводим ошибки на консоль, разделяя символом |
    Console.WriteLine(validationResult.ToString("|"));

Console.ReadLine();

/// <summary>
/// Модель для валидатора <see cref="RequestValidator"/>
/// </summary>
internal record Request
{
    /// <summary>
    /// Валидируемое свойство
    /// </summary>
    public required int InputInt { get; init; }
    /// <summary>
    /// Валидируемое свойство
    /// </summary>
    public required int? InputNullableInt { get; init; }
    /// <summary>
    /// Валидируемое свойство
    /// </summary>
    public required DateTime InputDateTime { get; init; }
}

/// <summary>
/// Валидатор для модели <see cref="Request"/>
/// </summary>
internal class RequestValidator : AbstractValidator<Request>
{
    public RequestValidator()
    {
        // Значение должно быть меньше чем 5
        RuleFor(request => request.InputInt).LessThan(5);
        // Значение должно быть меньше чем 5
        RuleFor(request => request.InputNullableInt).LessThan(5);
        // Значение должно быть меньше текущей даты/времени
        RuleFor(request => request.InputDateTime).LessThan(DateTime.Now);
    }
}

Проверим, что указанное значение меньше указанного значения свойства.

// Сигнатура валидатора
public static IRuleBuilderOptions<T, TProperty?> LessThan<T, TProperty>(
    this IRuleBuilder<T, TProperty?> ruleBuilder,
    Expression<Func<T, TProperty>> expression
) where TProperty : struct, IComparable<TProperty>, IComparable
using FluentValidation;
using FluentValidation.Results;

// Создаём модель и заполняем данными
Request request = new()
{
    LessThanInt = 5, // Используется в валидаторе для сравнения "Меньше чем это число"
    Input = 4,
};
// Создаём валидатор
RequestValidator validator = new();

// Валидируем модель, получаем результат
ValidationResult validationResult = validator.Validate(request);

// Валидация успешно пройдена?
if (validationResult.IsValid)
    Console.WriteLine("Валидация пройдена успешно!");
else
    // Выводим ошибки на консоль, разделяя символом |
    Console.WriteLine(validationResult.ToString("|"));

Console.ReadLine();

/// <summary>
/// Модель для валидатора <see cref="RequestValidator"/>
/// </summary>
internal record Request
{
    /// <summary>
    /// Меньше чем это число
    /// </summary>
    public required int LessThanInt { get; init; }
    /// <summary>
    /// Валидируемое свойство
    /// </summary>
    public required int? Input { get; init; }
}

/// <summary>
/// Валидатор для модели <see cref="Request"/>
/// </summary>
internal class RequestValidator : AbstractValidator<Request>
{
    public RequestValidator()
    {
        // Значение должно быть меньше чем 5
        RuleFor(request => request.Input)
            .LessThan(request => request.LessThanInt);
    }
}

Пример ошибки:

'Input' должно быть меньше '5'.

Доступные заполнители:

{PropertyName} — название валидируемого свойства

{PropertyValue} — значение валидируемого свойства

{PropertyPath} — полный путь к свойству

{ComparisonValue} — значение, с которым выполняется сравнение

{ComparisonProperty} — свойство, с которым выполняется сравнение

Пример кода с заполнителями 1 (используем свойство):

using FluentValidation;
using FluentValidation.Results;

// Создаём модель и заполняем данными
Request request = new()
{
    LessThanInt = 5, // Используется в валидаторе для сравнения "Меньше чем это число"
    Input = 5,
};
// Создаём валидатор
RequestValidator validator = new();

// Валидируем модель, получаем результат
ValidationResult validationResult = validator.Validate(request);

// Валидация успешно пройдена?
if (validationResult.IsValid)
    Console.WriteLine("Валидация пройдена успешно!");
else
    // Выводим ошибки на консоль, разделяя символом |
    Console.WriteLine(validationResult.ToString("|"));

Console.ReadLine();

/// <summary>
/// Модель для валидатора <see cref="RequestValidator"/>
/// </summary>
internal record Request
{
    /// <summary>
    /// Меньше чем это число
    /// </summary>
    public required int LessThanInt { get; init; }
    /// <summary>
    /// Валидируемое свойство
    /// </summary>
    public required int? Input { get; init; }
}

/// <summary>
/// Валидатор для модели <see cref="Request"/>
/// </summary>
internal class RequestValidator : AbstractValidator<Request>
{
    public RequestValidator()
    {
        // Значение должно быть меньше чем 5
        RuleFor(request => request.Input)
            .LessThan(request => request.LessThanInt)
            .WithMessage("""
                         PropertyName: {PropertyName}
                         PropertyValue: {PropertyValue}
                         PropertyPath: {PropertyPath}
                         ComparisonValue: {ComparisonValue}
                         ComparisonProperty: {ComparisonProperty}
                         """);
    }
}

Пример ошибки с заполнителями 1 (используем свойство):

PropertyName: Input
PropertyValue: 5
PropertyPath: Input
ComparisonValue: 5
ComparisonProperty: Less Than Int

Пример кода с заполнителями 2 (используем целочисленный литерал):

using FluentValidation;
using FluentValidation.Results;

// Создаём модель и заполняем данными
Request request = new()
{
    Input = 5,
};
// Создаём валидатор
RequestValidator validator = new();

// Валидируем модель, получаем результат
ValidationResult validationResult = validator.Validate(request);

// Валидация успешно пройдена?
if (validationResult.IsValid)
    Console.WriteLine("Валидация пройдена успешно!");
else
    // Выводим ошибки на консоль, разделяя символом |
    Console.WriteLine(validationResult.ToString("|"));

Console.ReadLine();

/// <summary>
/// Модель для валидатора <see cref="RequestValidator"/>
/// </summary>
internal record Request
{
    /// <summary>
    /// Валидируемое свойство
    /// </summary>
    public required int? Input { get; init; }
}

/// <summary>
/// Валидатор для модели <see cref="Request"/>
/// </summary>
internal class RequestValidator : AbstractValidator<Request>
{
    public RequestValidator()
    {
        // Значение должно быть меньше чем 5
        RuleFor(request => request.Input)
            .LessThan(5)
            .WithMessage("""
                         PropertyName: {PropertyName}
                         PropertyValue: {PropertyValue}
                         PropertyPath: {PropertyPath}
                         ComparisonValue: {ComparisonValue}
                         ComparisonProperty: {ComparisonProperty}
                         """);
    }
}

Пример ошибки с заполнителями 2 (используем целочисленный литерал):

PropertyName: Input
PropertyValue: 5
PropertyPath: Input
ComparisonValue: 5
ComparisonProperty: 

Валидатор LessThanOrEqualTo.

К списку валидаторов

Описание:

Гарантирует, что указанное значение, тип которого реализует интерфейс IComparable, будет меньше чем или равно указанному значению, тип которого также реализует интерфейс IComparable.

Исходный код валидатора.

Примеры кода:

Проверим, что указанное значение меньше или равно указанному значению.

// Сигнатуры перегрузок методов валидатора в примере кода.
// Есть и другие, но их опущу, они связаны с nullable типами.
public static IRuleBuilderOptions<T, TProperty> LessThanOrEqualTo<T, TProperty>(
    this IRuleBuilder<T, TProperty> ruleBuilder,
    TProperty valueToCompare
) where TProperty : IComparable<TProperty>, IComparable

public static IRuleBuilderOptions<T, TProperty?> LessThanOrEqualTo<T, TProperty>(
    this IRuleBuilder<T, TProperty?> ruleBuilder,
    TProperty valueToCompare
) where TProperty : struct, IComparable<TProperty>, IComparable
using FluentValidation;
using FluentValidation.Results;

// Создаём модель и заполняем данными
Request request = new()
{
    InputInt = 5,
    InputNullableInt = 5,
    InputDateTime = DateTime.Now,
};
// Создаём валидатор
RequestValidator validator = new();

// Валидируем модель, получаем результат
ValidationResult validationResult = validator.Validate(request);

// Валидация успешно пройдена?
if (validationResult.IsValid)
    Console.WriteLine("Валидация пройдена успешно!");
else
    // Выводим ошибки на консоль, разделяя символом |
    Console.WriteLine(validationResult.ToString("|"));

Console.ReadLine();

/// <summary>
/// Модель для валидатора <see cref="RequestValidator"/>
/// </summary>
internal record Request
{
    /// <summary>
    /// Валидируемое свойство
    /// </summary>
    public required int InputInt { get; init; }
    /// <summary>
    /// Валидируемое свойство
    /// </summary>
    public required int? InputNullableInt { get; init; }
    /// <summary>
    /// Валидируемое свойство
    /// </summary>
    public required DateTime InputDateTime { get; init; }
}

/// <summary>
/// Валидатор для модели <see cref="Request"/>
/// </summary>
internal class RequestValidator : AbstractValidator<Request>
{
    public RequestValidator()
    {
        // Значение должно быть меньше или равно 5-ти
        RuleFor(request => request.InputInt).LessThanOrEqualTo(5);
        // Значение должно быть меньше или равно 5-ти
        RuleFor(request => request.InputNullableInt).LessThanOrEqualTo(5);
        // Значение должно быть меньше или равно текущей дате/времени
        RuleFor(request => request.InputDateTime).LessThanOrEqualTo(DateTime.Now);
    }
}

Проверим, что указанное значение меньше или равно указанному значению свойства.

// Сигнатура валидатора
public static IRuleBuilderOptions<T, TProperty?> LessThanOrEqualTo<T, TProperty>(
    this IRuleBuilder<T, TProperty?> ruleBuilder,
    Expression<Func<T, TProperty>> expression
) where TProperty : struct, IComparable<TProperty>, IComparable
using FluentValidation;
using FluentValidation.Results;

// Создаём модель и заполняем данными
Request request = new()
{
    LessThanInt = 5, // Используется в валидаторе для сравнения "Меньше или равно этому числу"
    Input = 5,
};
// Создаём валидатор
RequestValidator validator = new();

// Валидируем модель, получаем результат
ValidationResult validationResult = validator.Validate(request);

// Валидация успешно пройдена?
if (validationResult.IsValid)
    Console.WriteLine("Валидация пройдена успешно!");
else
    // Выводим ошибки на консоль, разделяя символом |
    Console.WriteLine(validationResult.ToString("|"));

Console.ReadLine();

/// <summary>
/// Модель для валидатора <see cref="RequestValidator"/>
/// </summary>
internal record Request
{
    /// <summary>
    /// Меньше или равно этому числу
    /// </summary>
    public required int LessThanInt { get; init; }
    /// <summary>
    /// Валидируемое свойство
    /// </summary>
    public required int? Input { get; init; }
}

/// <summary>
/// Валидатор для модели <see cref="Request"/>
/// </summary>
internal class RequestValidator : AbstractValidator<Request>
{
    public RequestValidator()
    {
        // Значение должно быть меньше или равно 5-ти
        RuleFor(request => request.Input)
            .LessThanOrEqualTo(request => request.LessThanInt);
    }
}

Пример ошибки:

'Input' должно быть меньше или равно '5'.

Доступные заполнители:

{PropertyName} — название валидируемого свойства

{PropertyValue} — значение валидируемого свойства

{PropertyPath} — полный путь к свойству

{ComparisonValue} — значение, с которым выполняется сравнение

{ComparisonProperty} — свойство, с которым выполняется сравнение

Пример кода с заполнителями 1 (используем свойство):

using FluentValidation;
using FluentValidation.Results;

// Создаём модель и заполняем данными
Request request = new()
{
    LessThanInt = 5, // Используется в валидаторе для сравнения "Меньше или равно этому числу"
    Input = 6,
};
// Создаём валидатор
RequestValidator validator = new();

// Валидируем модель, получаем результат
ValidationResult validationResult = validator.Validate(request);

// Валидация успешно пройдена?
if (validationResult.IsValid)
    Console.WriteLine("Валидация пройдена успешно!");
else
    // Выводим ошибки на консоль, разделяя символом |
    Console.WriteLine(validationResult.ToString("|"));

Console.ReadLine();

/// <summary>
/// Модель для валидатора <see cref="RequestValidator"/>
/// </summary>
internal record Request
{
    /// <summary>
    /// Меньше или равно этому числу
    /// </summary>
    public required int LessThanInt { get; init; }
    /// <summary>
    /// Валидируемое свойство
    /// </summary>
    public required int? Input { get; init; }
}

/// <summary>
/// Валидатор для модели <see cref="Request"/>
/// </summary>
internal class RequestValidator : AbstractValidator<Request>
{
    public RequestValidator()
    {
        // Значение должно быть меньше или равно 5-ти
        RuleFor(request => request.Input)
            .LessThanOrEqualTo(request => request.LessThanInt)
            .WithMessage("""
                         PropertyName: {PropertyName}
                         PropertyValue: {PropertyValue}
                         PropertyPath: {PropertyPath}
                         ComparisonValue: {ComparisonValue}
                         ComparisonProperty: {ComparisonProperty}
                         """);
    }
}

Пример ошибки с заполнителями 1 (используем свойство):

PropertyName: Input
PropertyValue: 6
PropertyPath: Input
ComparisonValue: 5
ComparisonProperty: Less Than Int

Пример кода с заполнителями 2 (используем целочисленный литерал):

using FluentValidation;
using FluentValidation.Results;

// Создаём модель и заполняем данными
Request request = new()
{
    Input = 6,
};
// Создаём валидатор
RequestValidator validator = new();

// Валидируем модель, получаем результат
ValidationResult validationResult = validator.Validate(request);

// Валидация успешно пройдена?
if (validationResult.IsValid)
    Console.WriteLine("Валидация пройдена успешно!");
else
    // Выводим ошибки на консоль, разделяя символом |
    Console.WriteLine(validationResult.ToString("|"));

Console.ReadLine();

/// <summary>
/// Модель для валидатора <see cref="RequestValidator"/>
/// </summary>
internal record Request
{
    /// <summary>
    /// Валидируемое свойство
    /// </summary>
    public required int? Input { get; init; }
}

/// <summary>
/// Валидатор для модели <see cref="Request"/>
/// </summary>
internal class RequestValidator : AbstractValidator<Request>
{
    public RequestValidator()
    {
        // Значение должно быть меньше или равно 5-ти
        RuleFor(request => request.Input)
            .LessThanOrEqualTo(5)
            .WithMessage("""
                         PropertyName: {PropertyName}
                         PropertyValue: {PropertyValue}
                         PropertyPath: {PropertyPath}
                         ComparisonValue: {ComparisonValue}
                         ComparisonProperty: {ComparisonProperty}
                         """);
    }
}

Пример ошибки с заполнителями 2 (используем целочисленный литерал):

PropertyName: Input
PropertyValue: 6
PropertyPath: Input
ComparisonValue: 5
ComparisonProperty: 

← Предыдущая часть

Комментарии (1)


  1. jaanq
    20.08.2024 08:40

    Похоже на то, что вы велосипедите свои регулярки с небольшим добавлением плюшек