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:
1RuleFor(request => request.ZipFile)2 .MustBeValidZipFile();
which uses the following extension method:
1public static IRuleBuilderOptions<T, IFormFile> MustBeValidZipFile<T>(2 this IRuleBuilder<T, IFormFile> ruleBuilder)3{4 return ruleBuilder5 .NotNull()6 .WithMessage(ValidationMessages.FileIsNull)7 .Must(file => file.FileName.Length < MaxFilenameSize)8 .WithMessage(ValidationMessages.FilenameTooLong)9 .Must(file => file.Length > 0)10 .WithMessage(ValidationMessages.FileSizeMustNotBeZero)11 .Must(file => file.FileName.ToLower().EndsWith(".zip"))12 .WithMessage(ValidationMessages.ZipFilenameMustEndDotZip);13}
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.
1RuleFor(request => request.ZipFile)2 .Cascade(CascadeMode.Stop)3 .MustBeValidZipFile();
This is covered in the FluentValidation documentation, but is tucked away under "other features" and not immediately obvious.
