Trending:
Software Development

FluentValidation's deprecated auto-validation forces .NET teams to rethink pipeline integration

FluentValidation.AspNetCore's automatic validation is deprecated since v11.9.1, pushing enterprise teams toward manual controller validation or MediatR behaviors. The shift coincides with growing consensus: one validator per request, not generic validators.

The deprecated package problem

FluentValidation.AspNetCore, the library that auto-wired validation into ASP.NET Core's request pipeline, is deprecated as of v11.9.1. Teams still using AddFluentValidationAutoValidation() are running on borrowed time.

The maintainers now recommend manual validation in controllers or pipeline behaviors. This isn't a minor API change. It's a philosophy shift: validation as explicit orchestration, not framework magic.

What this means in practice

FluentValidation itself remains the de facto standard for complex .NET validation. It beats Data Annotations for enterprise APIs because rules live in testable, reusable validator classes instead of attribute soup on DTOs.

The pattern that's emerged: one validator per request DTO. CreateUserRequestValidator, UpdateUserRequestValidator, CreateOrderRequestValidator. Each API contract gets its own rule set.

Generic validators, the "clever" approach of handling multiple request types in one validator class, are officially a bad idea. They become God classes full of conditional logic. You lose type safety. You break single responsibility. Every experienced team learns this the hard way.

The new integration playbook

Without auto-validation, you have three paths:

  1. Manual in controllers: Call await validator.ValidateAsync() before your handler logic. Simple, explicit, verbose.
  2. Action filters: Build a custom filter that runs validation and returns 400s automatically. Cleaner controllers, more setup.
  3. MediatR pipeline behaviors: If you're using CQRS, validate in a behavior before handlers execute. Centralizes validation for request/response patterns.

Most teams landing on option 3 for new systems. Option 1 for legacy codebases that can't justify the refactor.

The reusability question

You can still share validation logic without generic validators. Extension methods on IRuleBuilder let you define reusable rules like ValidEmail() or ValidPhoneNumber() that compose into request-specific validators.

This keeps individual validators clean while avoiding duplication. It's the middle path between copy-paste chaos and the abstraction trap.

What to watch

Integration with Swashbuckle for OpenAPI doc generation still works but requires manual wiring now. Teams generating Swagger specs from FluentValidation rules need to update their setup.

Performance implications matter for high-throughput APIs. Async validators in request-scoped DI containers can leak memory if improperly registered. Singleton validators are faster but can't inject scoped dependencies like DbContext. The trade-offs are real.

The real question

Is the deprecation a problem? Only if you treat automatic validation as a requirement instead of a convenience. FluentValidation's value was never the ASP.NET Core integration. It was separating validation from models, making rules testable, and handling complexity that attributes can't.

That hasn't changed. How you wire it into your pipeline has.