In situations where your validation message should display a non-standard value, or a value which isn't already available as a FluentValidation placeholder, you can add your own name/value pair to the validation context for use in messaging.
In the following example, the object being validated is a MemoryStream
, and we're making sure it is not an empty stream by validating that it is greater than 0 bytes in length.
The default message placeholders available in this situation, {PropertyName}
and {PropertyValue}
, would output the values "FileStream" and "System.IO.MemoryStream" respectively, neither of which are suitable for this particular validation message as the message should reference the name of the file which the stream was created from, and this is stored in the FileName
property.
public record DataSetFileDto
{
public required string FileName { get; set; }
public required MemoryStream FileStream { get; set; }
public class Validator : AbstractValidator<DataSetFileDto>
{
public Validator()
{
RuleFor(dto => dto.FileStream)
.Must((dto, fileStream, context) =>
{
context.MessageFormatter.AppendArgument("FileName", dto.FileName);
return fileStream.Length > 0;
})
.WithMessage(ValidationMessages.FileSizeMustNotBeZero, "{FileName}");
}
}
}
This overload of Must
has three parameters:
- the root object being validated (
dto
), in this case theDataSetFileDto
- the property being validated (
fileStream
), in this case theMemoryStream
- the validation context (
context
)
The first part of the Must
statement block creates a placeholder name and assigns the value it should reference, and the second part performs the boolean validation, in this case ensuring the file is not empty.