If you are validating a reference type which can be null, along with its properties, you may encounter a situation where the parent object being null causes FluentValidation to throw a NullReferenceException
when validating the properties on that object.
Take the following rule in a custom Validator
class:
RuleFor(request => request.ZipFile)
.MustBeValidZipFile();
which uses the following extension method:
public static IRuleBuilderOptions<T, IFormFile> MustBeValidZipFile<T>(
this IRuleBuilder<T, IFormFile> ruleBuilder)
{
return ruleBuilder
.NotNull()
.WithMessage(ValidationMessages.FileIsNull)
.Must(file => file.FileName.Length < MaxFilenameSize)
.WithMessage(ValidationMessages.FilenameTooLong)
.Must(file => file.Length > 0)
.WithMessage(ValidationMessages.FileSizeMustNotBeZero)
.Must(file => file.FileName.ToLower().EndsWith(".zip"))
.WithMessage(ValidationMessages.ZipFilenameMustEndDotZip);
}
Even though the IFormFile
is null
, subsequent checks on its properties will continue to be performed, therefore, attempting to check the FileName
property on that object will result in a NullReferenceException
.
This can be avoided by using the Cascade
method to stop execution on the first error.
RuleFor(request => request.ZipFile)
.Cascade(CascadeMode.Stop)
.MustBeValidZipFile();
This is covered in the FluentValidation documentation, but is tucked away under "other features" and not immediately obvious.