Model validation is an important feature in ASP.NET Core MVC that helps us verify that the data entered by users matches expectations.
Validation with data annotations
See the Microsoft data annotations documentation.
public class User
{
[Required]
[StringLength(32)]
public string Name { get; set; }
[Required]
[EmailAddress]
public string Email { get; set; }
}
Validation with fluent chaining
FluentValidation is a .NET library for building type-safe validation rules. Its design goal is to provide a simple, clear API while still supporting complex validation rules.
See the official FluentValidation documentation.
dotnet add package FluentValidation.AspNetCore
Implementing a validator
public class UserValidator : AbstractValidator<User>
{
public UserValidator()
{
RuleFor(x => x.Name).NotEmpty().MaximumLength(32);
RuleFor(x => x.Email).NotEmpty().EmailAddress();
}
}
Automatic dependency injection
services.AddValidatorsFromAssembly(assembly).AddFluentValidationAutoValidation();
ValidatorOptions.Global.LanguageManager = new CustomFluentValidationLanguageManager();
Custom validation error messages
public class UserValidator : AbstractValidator<User>
{
public UserValidator()
{
RuleFor(x => x.Name).NotEmpty().MaximumLength(32).WithMessage("Name is required and must be less than 32 characters.");
RuleFor(x => x.Email).NotEmpty().EmailAddress().WithMessage("Email is required and must be a valid email address.");
}
}
Custom validation logic
public class UserCreateRequestValidator : AbstractValidator<UserCreateRequest>
{
public UserCreateRequestValidator(IdentityDbContext context)
{
RuleFor(m => m.UserName).NotNull().NotEmpty().Length(5, 20).Matches("^[a-zA-Z]+$");
RuleFor(m => m.PhoneNumber).NotNull().NotEmpty().Length(11).Matches(@"^1\d{10}$").Must((model, phoneNumber) =>
{
return !context.Users.Any(e => e.PhoneNumber == phoneNumber);
});
RuleFor(m => m.Password).NotNull().NotEmpty().Length(5, 20);
RuleFor(m => m.Email).EmailAddress().Length(5, 50);
}
}
Common error messages
public class CustomFluentValidationLanguageManager : FluentValidation.Resources.LanguageManager
{
public CustomFluentValidationLanguageManager()
{
AddTranslation("en", "NotNullValidator", "The {PropertyName} field is required.");
AddTranslation("en", "MaximumLengthValidator", "The {PropertyName} field must be less than {MaxLength} characters.");
AddTranslation("en", "EmailAddressValidator", "The {PropertyName} field must be a valid email address.");
}
}