Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add optional filter to AddFluentValidationAutoValidation() #20

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -37,22 +37,31 @@ namespace FluentValidation.AspNetCore;
public class FluentValidationModelValidatorProvider : IModelValidatorProvider {
private readonly bool _implicitValidationEnabled;
private readonly bool _implicitRootCollectionElementValidationEnabled;
private readonly Func<Type, bool> _filter;

public FluentValidationModelValidatorProvider(bool implicitValidationEnabled)
: this(implicitValidationEnabled, false) {
: this(implicitValidationEnabled, false, default) {
}

public FluentValidationModelValidatorProvider(
bool implicitValidationEnabled,
bool implicitRootCollectionElementValidationEnabled) {
bool implicitRootCollectionElementValidationEnabled)
: this(implicitValidationEnabled, implicitRootCollectionElementValidationEnabled, default) {
}

public FluentValidationModelValidatorProvider(
bool implicitValidationEnabled,
bool implicitRootCollectionElementValidationEnabled,
Func<Type, bool> filter) {
JeremySkinner marked this conversation as resolved.
Show resolved Hide resolved
_implicitValidationEnabled = implicitValidationEnabled;
_implicitRootCollectionElementValidationEnabled = implicitRootCollectionElementValidationEnabled;
_filter = filter;
}

public virtual void CreateValidators(ModelValidatorProviderContext context) {
context.Results.Add(new ValidatorItem {
IsReusable = false,
Validator = new FluentValidationModelValidator(_implicitValidationEnabled, _implicitRootCollectionElementValidationEnabled),
Validator = new FluentValidationModelValidator(_implicitValidationEnabled, _implicitRootCollectionElementValidationEnabled, _filter),
});
}
}
Expand All @@ -63,16 +72,25 @@ public FluentValidationModelValidatorProvider(bool implicitValidationEnabled)
public class FluentValidationModelValidator : IModelValidator {
private readonly bool _implicitValidationEnabled;
private readonly bool _implicitRootCollectionElementValidationEnabled;
private readonly Func<Type, bool> _filter;

public FluentValidationModelValidator(bool implicitValidationEnabled)
: this(implicitValidationEnabled, false) {
: this(implicitValidationEnabled, false, default) {
}

public FluentValidationModelValidator(
bool implicitValidationEnabled,
bool implicitRootCollectionElementValidationEnabled) {
bool implicitRootCollectionElementValidationEnabled)
: this(implicitValidationEnabled, implicitRootCollectionElementValidationEnabled, default) {
}

public FluentValidationModelValidator(
bool implicitValidationEnabled,
bool implicitRootCollectionElementValidationEnabled,
Func<Type, bool> filter) {
JeremySkinner marked this conversation as resolved.
Show resolved Hide resolved
_implicitValidationEnabled = implicitValidationEnabled;
_implicitRootCollectionElementValidationEnabled = implicitRootCollectionElementValidationEnabled;
_filter = filter;
}

public virtual IEnumerable<ModelValidationResult> Validate(ModelValidationContext mvContext) {
Expand Down Expand Up @@ -140,6 +158,12 @@ public FluentValidationModelValidator(bool implicitValidationEnabled)
}

protected bool ShouldSkip(ModelValidationContext mvContext) {
//Apply custom filter (if specified)
//validation will be skipped unless we match on this filter
if (_filter != null && !_filter.Invoke(mvContext.ModelMetadata.ModelType)) {
return true;
}

// Skip if there's nothing to process.
if (mvContext.Model == null) {
return true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,15 @@ public class FluentValidationAutoValidationConfiguration {
/// Setting this to true will disable DataAnnotations and only run FluentValidation.
/// </summary>
public bool DisableDataAnnotationsValidation { get; set; }


/// <summary>
/// When specified, automatic validation will only apply to the types matched by the filter.
/// If the filter does not match, automatic validation will not be applied. This can be useful
/// for specific situations where you want to opt in/out of automatic validation
/// Example: Filter = type => type == typeof(Model)
/// </summary>
public Func<Type, bool> Filter { get; set; }
}

/// <summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,8 @@ public static class FluentValidationMvcExtensions {
if (!options.ModelValidatorProviders.Any(x => x is FluentValidationModelValidatorProvider)) {
options.ModelValidatorProviders.Insert(0, new FluentValidationModelValidatorProvider(
config.ImplicitlyValidateChildProperties,
config.ImplicitlyValidateRootCollectionElements));
config.ImplicitlyValidateRootCollectionElements,
config.Filter));
}
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,22 @@ public IActionResult UsingEnumerable([FromBody]IEnumerable<TestModel5> model)
return TestResult();
}

public ActionResult AutoFilter(AutoFilterModel test) {
return TestResult();
}

public ActionResult AutoFilterParent(AutoFilterParentModel test) {
return TestResult();
}

public ActionResult AutoFilterRootCollection(List<AutoFilterModel> test) {
return TestResult();
}

public ActionResult AutoFilterParentWithCollection(AutoFilterParentWithCollectionModel test) {
return TestResult();
}

private ActionResult TestResult() {
var errors = new List<SimpleError>();

Expand Down
Loading