An unobtrusive extension to FluentValidations for documenting validation rules.
- Install ValiDoc via NuGet
Install-Package ValiDoc -Pre
- Configure Dependency Injection
public void ConfigureServices(IServiceCollection services)
{
// Add ValiDoc dependencies
services.AddValiDoc();
}
- Reference ValiDoc namespace
using ValiDoc;
- Constructor Inject the RuleDescriptor
private readonly IRuleBuilder _ruleBuilder;
public ValidationController(IRuleBuilder ruleBuilder)
{
_ruleBuilder = ruleBuilder;
}
- Create an instance of DocBuilder that will be used to build the documentation
var docBuilder = new DocBuilder(_ruleBuilder);
- Invoke the .Document() method on the DocBuilder, passing in an implementation of AbstractValidator<T>
var ruleDocumentation = docBuilder.Document(myValidatorInstance);
public class MultipleRuleSingleChildValidator : AbstractValidator<Person>
{
public MultipleRuleSingleChildValidator()
{
RuleFor(p => p.FirstName).NotEmpty();
RuleFor(p => p.LastName).NotEmpty().MaximumLength(20);
RuleFor(p => p.Address).SetValidator(new AddressValidator());
}
}
[Route("api/[controller]")]
public class ValidationController : Controller
{
private readonly IRuleBuilder _ruleBuilder;
public ValidationController(IRuleBuilder ruleBuilder)
{
_ruleBuilder = ruleBuilder;
}
[HttpGet]
public IEnumerable<RuleDescriptor> ValidatorDocumentation()
{
var validator = new MultipleRuleSingleChildValidator();
var docBuilder = new ValiDoc.DocBuilder(_ruleBuilder);
return docBuilder.Document(validator);
}
}
[
{
"memberName": "First Name",
"rules": [
{
"validatorName": "NotEmptyValidator",
"failureSeverity": "Error",
"onFailure": "Continue",
"validationMessage": "'First Name' should not be empty."
}
]
},
{
"memberName": "Last Name",
"rules": [
{
"validatorName": "NotEmptyValidator",
"failureSeverity": "Error",
"onFailure": "Continue",
"validationMessage": "'Last Name' should not be empty."
},
{
"validatorName": "MaximumLengthValidator",
"failureSeverity": "Error",
"onFailure": "Continue",
"validationMessage": "'Last Name' must be less than {MaxLength} characters. You entered {TotalLength} characters."
}
]
},
{
"memberName": "Address",
"rules": [
{
"validatorName": "AddressValidator",
"failureSeverity": "Error",
"onFailure": "Continue",
"validationMessage": "N/A - Refer to specific AddressValidator documentation"
}
]
}
]
- Extraction of validation messages (Configured argument values not included)
- Built in validators
- Chained validators for the same property
- Complex properties
- Cascade behaviour
- Collections
- RuleSets
- .WithMessage()
- .WithName()
- Validation arguments (Greater than 10 characters for example)
- Custom validators
- .Must()