FluentValidation.AutoValidation
FluentValidation.AutoValidation copied to clipboard
MVC AutoValidation not performed with a null binding source.
I have a dotnet 8 MVC project I'm working with that uses binding that does define the source ([FromBody], [FromQuery]) and I have several hundred throughout the project like this
ex
public IActionResult PostForm(FormObject obj) { ...
As a result, the binding source is null (this is not an APIController so inferred binding rules are not applied). Debugging into the runtime shows that when the binding source is null, and is not inferred, the ValueProviders simply go through each one to binding where it can:
DefaultModelBindingContext.cs
private static IValueProvider FilterValueProvider(IValueProvider valueProvider, BindingSource? bindingSource)
{
if (bindingSource == null || bindingSource.IsGreedy)
{
return valueProvider;
}
if (valueProvider is not IBindingSourceValueProvider bindingSourceValueProvider)
{
return valueProvider;
}
return bindingSourceValueProvider.Filter(bindingSource) ?? EmptyValueProvider;
}
My problem comes in FluentValidationAutoValidationActionFilter where is is trying to determine if it has a valid binding source, but null is not allowed.
if (subject != null && parameterType.IsCustomType() &&
!hasAutoValidateNeverAttribute && (hasAutoValidateAlwaysAttribute || HasValidBindingSource(bindingSource)) &&
serviceProvider.GetValidator(parameterType) is IValidator validator)
My workaround is to replace the built-in filter with a customer version above which accepts null as a valid binding source. Can this be provided by default with the library, or can you advise a solution that doesn't involve adding the alwaysvalidate attribute to every method that needs it? I attempted to add the InferParameterBindingInfoConvention that ApiControllers to use MVC controllers however it did not accurately determine the binding and broke most methods in the application.
Thanks!
Hi there, currently thinking about a EnableNullBindingSourceAutomaticValidation with a default value of false. So you could enable that one from the configuration. When enabled and the binding source is null the check will pass and your validators will run.