Как реализовать валидацию входных данных в ASP.NET Core?

«Как реализовать валидацию входных данных в ASP.NET Core?» — вопрос из категории ASP.NET Core, который задают на 25% собеседований C# Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

ASP.NET Core предоставляет несколько встроенных и сторонних способов для валидации моделей.

1. Атрибуты валидации (DataAnnotations) Стандартный подход для простых правил. Активируется автоматически при использовании [ApiController].

public class CreateUserRequest
{
    [Required(ErrorMessage = "Name is required.")]
    [StringLength(100, MinimumLength = 2)]
    public string Name { get; set; }

    [EmailAddress]
    public string Email { get; set; }

    [Range(18, 120)]
    public int Age { get; set; }
}

2. FluentValidation (Рекомендуется для сложной логики) Библиотека для декларативного описания правил. Требует регистрации в Program.cs.

public class CreateUserRequestValidator : AbstractValidator<CreateUserRequest>
{
    public CreateUserRequestValidator()
    {
        RuleFor(x => x.Name).NotEmpty().Length(2, 100);
        RuleFor(x => x.Email).EmailAddress();
        RuleFor(x => x.Age).InclusiveBetween(18, 120);
        // Сложное правило
        RuleFor(x => x.Email)
            .Must(email => email.EndsWith("@company.com"))
            .WithMessage("Only company emails are allowed.");
    }
}
// Регистрация: builder.Services.AddScoped<IValidator<CreateUserRequest>, CreateUserRequestValidator>();

3. Валидация в Action-методе С атрибутом [ApiController] невалидная модель автоматически приводит к ответу 400 BadRequest с деталями в ModelState. Вручную можно проверить так:

[HttpPost]
public IActionResult CreateUser(CreateUserRequest request)
{
    if (!ModelState.IsValid) // Автоматически проверяется
    {
        return ValidationProblem(ModelState); // Возвращает стандартизированную ошибку
    }
    // Логика обработки...
}

4. Пользовательские атрибуты валидации

public class FutureDateAttribute : ValidationAttribute
{
    protected override ValidationResult IsValid(object value, ValidationContext context)
    {
        if (value is DateTime date && date > DateTime.Now)
            return ValidationResult.Success;
        return new ValidationResult("Date must be in the future.");
    }
}

Best Practices:

  • Всегда валидируйте входные данные на уровне контроллера.
  • Для бизнес-правил используйте валидацию внутри доменного слоя.
  • Используйте ProblemDetails для стандартизации ответов об ошибках.