Client-side validation provides a great user experience but this must always be backed up by server-side validation.
Figure: Client-side validation does not provide effective data security for your Web API endpoints
.NET and .NET Core Web APIs provide built-in support for validation using Data Annotations:
Fluent Validation improves the built-in capabilities in a number of ways:
using FluentValidation;public class CustomerValidator: AbstractValidator<Customer> {public CustomerValidator() {RuleFor(x => x.Surname).NotEmpty();RuleFor(x => x.Forename).NotEmpty().WithMessage("Please specify a first name");RuleFor(x => x.Discount).NotEqual(0).When(x => x.HasDiscount);RuleFor(x => x.Address).Length(20, 250);RuleFor(x => x.Postcode).Must(BeAValidPostcode).WithMessage("Please specify a valid postcode");}private bool BeAValidPostcode(string postcode) {// custom postcode validating logic goes here}}
✅ Good example: Fluent Validation uses LINQ expressions allowing the development of powerful, type-checked rulesets without needing to modify the class under validation.
RuleFor(x => x.Discount).NotEqual(0).When(x => x.HasDiscount);
✅ Good Example: Conditional validation with the .When() clause allows for complex logic such as “Discount number cannot be 0 if the HasDiscount boolean is true”
{"CompanyName": ["The CompanyName field is required."]}
✅ Good Example: This is the JSON returned from Fluent Validation when a validation rule fails. This is exactly the same format as what would be returned by the built-in ModelState validation.