Introduction
ShopNest Order API must reject invalid orders server-side — FluentValidation expresses complex rules (stock check, duplicate order) cleaner than Data Annotations alone.
After this article you will
- Validate DTOs with Data Annotations
- Build AbstractValidator rules with FluentValidation
- Async validation against database
- Return ProblemDetails for validation errors
- Validate nested objects and collections
Prerequisites
- Article 38 — Swagger / OpenAPI
- ShopNest with EF Core and auth from Modules 2–4
Concept deep-dive
public class CreateOrderValidator : AbstractValidator<CreateOrderDto>
{
private readonly IProductRepository _products;
public CreateOrderValidator(IProductRepository products)
{
_products = products;
RuleFor(x => x.CustomerId).NotEmpty();
RuleFor(x => x.Lines).NotEmpty();
RuleForEach(x => x.Lines).ChildRules(line =>
{
line.RuleFor(l => l.Quantity).GreaterThan(0);
line.RuleFor(l => l.ProductId).GreaterThan(0);
});
RuleFor(x => x).MustAsync(HasStockAsync)
.WithMessage("Insufficient stock for one or more items");
}
}
builder.Services.AddFluentValidationAutoValidation();
builder.Services.AddValidatorsFromAssemblyContaining<CreateOrderValidator>();
Invalid request → automatic 400 with ProblemDetails errors extension listing field messages.
Hands-on — ShopNest Order Processing API
- CreateOrderDto + CreateOrderValidator with async stock check.
- POST invalid order — verify 400 ProblemDetails JSON.
- Custom rule: order total must match line sum.
Common errors & best practices
- Trusting client-side validation only — always validate server-side.
- Validation in controller — pollutes actions; use validators.
- Throwing Exception for validation — use 400 ProblemDetails instead.
Interview questions
Q: FluentValidation vs Data Annotations?
A: Annotations for simple rules; FluentValidation for complex, async, testable rules.
Q: Never trust client?
A: Any client can call API directly — server validation is mandatory.
Summary
- FluentValidation keeps order rules readable and testable
- Async validators query DB for stock and uniqueness
- ProblemDetails standardizes 400 validation responses
- Child validators handle order line collections
Previous: Swagger / OpenAPI
Next: Pagination, Filtering and Sorting
FAQ
Validation filter vs middleware?
AutoValidation runs before action — preferred for APIs.
Validate nested DTOs?
RuleForEach + ChildRules or SetValidator on child type.