Sử dụng Must với custom validation method để kiểm tra logic phức tạp như DateOfBirth.
Ví dụ hoàn chỉnh
using FluentValidation;
using FluentValidation.Results;
using System;
using System.Collections.Generic;
public class Person
{
public string FirstName { get; set; }
public DateTime DateOfBirth { get; set; }
}
public class PersonValidator : AbstractValidator<Person>
{
public PersonValidator()
{
RuleFor(p => p.DateOfBirth)
.NotEmpty().WithMessage("{PropertyName} is required")
.Must(BeValidDateOfBirth).WithMessage("{PropertyName} must be in the past and not older than 120 years");
}
private bool BeValidDateOfBirth(DateTime dob)
{
int currentYear = DateTime.Now.Year;
int dobYear = dob.Year;
// Năm sinh <= năm hiện tại VÀ > (hiện tại - 120)
return dobYear <= currentYear && dobYear > (currentYear - 120);
}
}
class Program
{
static void Main()
{
var person = new Person
{
FirstName = "Test",
DateOfBirth = DateTime.Now.AddYears(1) // Năm sau -> Invalid
};
var validator = new PersonValidator();
ValidationResult result = validator.Validate(person);
if (!result.IsValid)
{
foreach (var error in result.Errors)
Console.WriteLine($"[{error.PropertyName}] {error.ErrorMessage}");
}
else
{
Console.WriteLine("Valid!");
}
Console.ReadLine();
}
}
Kết quả
[DateOfBirth] DateOfBirth must be in the past and not older than 120 years
Cải tiến: Tách validator reusable
public static class DateValidators
{
public static IRuleBuilderOptions<T, DateTime> ValidDateOfBirth<T>(
this IRuleBuilder<T, DateTime> ruleBuilder,
int maxAge = 120)
{
return ruleBuilder
.Must(dob =>
{
var now = DateTime.Now;
var age = now.Year - dob.Year;
if (dob > now.AddYears(-age)) age--; // Chưa tới sinh nhật năm nay
return age >= 0 && age <= maxAge;
})
.WithMessage("{PropertyName} must be a valid date of birth (age 0-{MaxAge})");
}
}
// Sử dụng
RuleFor(p => p.DateOfBirth).ValidDateOfBirth(120);
Validation so sánh với DateTime khác
// DateOfBirth phải trước HireDate
RuleFor(p => p.DateOfBirth)
.LessThan(p => p.HireDate)
.WithMessage("Date of birth must be before hire date");
// DateOfBirth phải >= 18 tuổi so với hôm nay
RuleFor(p => p.DateOfBirth)
.LessThanOrEqualTo(DateTime.Today.AddYears(-18))
.WithMessage("Must be at least 18 years old");
Lưu ý
Mustchạy sau các validator trước (NotEmpty, etc.) nếu không dùngCascadeMode.StopOnFirstFailure.- Trong ASP.NET Core, validator tự động chạy khi binding model. Trả về 400 Bad Request với errors.
- Dùng
DateOnly(NET 6+) thayDateTimecho DateOfBirth để tránh vấn đề timezone.