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:
- Manual in controllers: Call
await validator.ValidateAsync()before your handler logic. Simple, explicit, verbose. - Action filters: Build a custom filter that runs validation and returns 400s automatically. Cleaner controllers, more setup.
- 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.