-
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Description
2024 Update
The entire FluentValidation.AspNetCore package has been deprecated, and we no longer recommend using the automatic validation integration that this package provided. This is due to several reasons:
- The ASP.NET Core validation pipeline is not asynchronous, which limits which FluentValidation features can be used
- Support and maintenance for the ASP.NET Core integration is too time consuming
- Automatic validation makes it hard to see where validators are actually used, which makes it difficult to navigate codebases
The core FluentValidation package remains fully supported. We recommend using a manual validation approach with ASP.NET projects, as documented here
The original post, which outlined deprecation of several features but not the whole package, remains below.
Background
FluentValidation supports several features that only work within ASP.NET Core MVC-based projects. Back when MVC was the only way to build web applications, this seemed reasonable. However, ASP.NET now provides several alternatives to MVC (including Minimal APIs and Razor) where these features can't be used.
Our aim with FluentValidation going forward is to provide a mostly uniform experience when working with different web frameworks (as well as desktop/console apps) and we encourage developers to design their validators in a way that's agnostic of which web framework you're using. As such, we will be deprecating several MVC-specific features starting with release 11.1 including:
- The
InjectValidatormethod - Implicit validation of child properties (
ImplicitlyValidateChildProperties) - Implicit validation of root collection elements (
ImplicitlyValidateRootCollectionElements)
Deprecation of InjectValidator
The InjectValidator method allowed you to implicitly inject a child validator from the ASP.NET Service Provider.
public class PersonValidator : AbstractValidator<Person>
{
public PersonValidator()
{
RuleFor(x => x.Address).InjectValidator();
}
}Assuming that the address property is of type Address, the above code would attempt to resolve an IValidator<Address> and use this to validator the Address property. This method can only be used when working with ASP.NET MVC's auto-validation feature and cannot be used in other contexts.
Instead of using InjectValidator, we instead recommend using a more traditional constructor injection approach, which is not just limited to ASP.NET MVC:
public class PersonValidator : AbstractValidator<Person>
{
public PersonValidator(IValidator<Address> addressValidator)
{
RuleFor(x => x.Address).SetValidator(addressValidator);
}
}Deprecation of implicit child validation
By default, when validating complex object graphs you must explicitly specify any child validators for complex properties by using SetValidator (see the docs). However, within ASP.NET Core MVC projects you can also optionally enable implicit validation for child properties. When this is enabled, instead of having to specify child validators using SetValidator, MVC’s validation infrastructure will recursively attempt to automatically find validators for each property.
This was enabled in application startup by setting the ImplicitlyValidateChildProperties property:
services.AddMvc().AddFluentValidation(fv =>
{
fv.ImplicitlyValidateChildProperties = true;
});This approach to validation only works when auto-validation is enabled within MVC-specific projects and is not usable in other project types, or when MVC auto-validation is disabled. Additionally, this feature has a high maintenance burden and requires several workarounds in order to implement. As such, this approach is being deprecated. To migrate you should do the following:
- Explicitly wire up any child validators using
SetValidator(docs) - Remove the call to
ImplicitlyValidateChildProperties = true;from your application startup. - Replace the call to
AddFluentValidationwithAddFluentValidationAutoValidation(and optionallyAddFluentValidationClientsideAdapters) as per Announcement: Changes to ASP.NET Integration registration methods (AddFluentValidation()) #1965
Deprecation of implicit validation of root collection elements
By default, you must create a specific collection validator or enable implicit child property validation to validate a model that is of a collection type. For example, no validation of the following model will occur with the default settings unless you define a validator that inherits from AbstractValidator<List<Person>>.
public ActionResult DoSomething(List<Person> people) => Ok();Implicit collection of root collections allows you to validate the contents of the collection without having to enable implicit child validation (above) or define a validator for List<T>.
Similarly to implicit child validation, this feature only works in the context of ASP.NET MVC's auto-validation and could be enabled in your application startup routine:
services.AddMvc().AddFluentValidation(fv =>
{
fv.ImplicitlyValidateRootCollectionElements = true;
});As with implicit child validation, this feature is specific to ASP.NET MVC's auto-validation and also has a high maintenance burden. As such it is being deprecated. To migrate, we recommend defining an explicit collection validator:
public class PersonCollectionValidator : AbstractValidator<List<Person>>
{
public PersonCollectionValidator()
{
RuleForEach(self => self).SetValidator(new PersonValidator());
}
}Alternatively, switch to accepting a single object as the root model and expose the collection as a property instead.