Data Validation in C# (.NET): A Complete Guide
Data validation is one of the key aspects of developing reliable and secure applications in C#. It ensures that input data meets the expected format, value ranges, and business rules. The .NET ecosystem offers several powerful tools for validation: from built-in System.ComponentModel.DataAnnotations attributes to the flexible FluentValidation library. In this article, we will thoroughly examine both approaches with code examples.
1. Built-in Validation via DataAnnotations
The System.ComponentModel.DataAnnotations namespace provides a set of attributes that can be applied to model class properties. This is the simplest and fastest way to validate, especially in ASP.NET Core MVC and Blazor.
Main attributes:
[Required]— the value cannot benullor empty.[StringLength(max)]— limits the length of a string.[Range(min, max)]— checks numeric ranges.[RegularExpression(pattern)]— validation using a regular expression.[EmailAddress]— email validation.[Compare("OtherProperty")]— compares two properties (e.g., password and confirmation).
Example model with attributes:
public class UserRegistrationDto{ [Required(ErrorMessage = "Name is required")] [StringLength(50, MinimumLength = 2, ErrorMessage = "Name must be between 2 and 50 characters")] public string FirstName { get; set; }
[Required(ErrorMessage = "Email is required")] [EmailAddress(ErrorMessage = "Invalid email format")] public string Email { get; set; }
[Required] [Range(18, 120, ErrorMessage = "Age must be between 18 and 120")] public int Age { get; set; }
[Required] [DataType(DataType.Password)] public string Password { get; set; }
[Compare("Password", ErrorMessage = "Passwords do not match")] public string ConfirmPassword { get; set; }}Manual model validation:
public static bool ValidateUser(UserRegistrationDto user, out List<ValidationResult> errors){ var context = new ValidationContext(user); errors = new List<ValidationResult>(); return Validator.TryValidateObject(user, context, errors, validateAllProperties: true);}
// Usage:var user = new UserRegistrationDto { FirstName = "A", Email = "invalid", Age = 15 };if (!ValidateUser(user, out var errors)){ foreach (var error in errors) Console.WriteLine(error.ErrorMessage);}2. FluentValidation — Advanced Validation
The FluentValidation library (NuGet: FluentValidation.AspNetCore) offers a more flexible and readable way to define validation rules using a fluent interface. It is ideal for complex scenarios: conditional validation, custom messages, rule chains, and integration with DI containers.
Installation via NuGet:
dotnet add package FluentValidation.AspNetCoreExample validator:
using FluentValidation;
public class UserValidator : AbstractValidator<UserRegistrationDto>{ public UserValidator() { RuleFor(u => u.FirstName) .NotEmpty().WithMessage("Name cannot be empty") .Length(2, 50).WithMessage("Name must be between 2 and 50 characters");
RuleFor(u => u.Email) .NotEmpty().WithMessage("Email is required") .EmailAddress().WithMessage("Invalid email format");
RuleFor(u => u.Age) .InclusiveBetween(18, 120).WithMessage("Age must be between Also in library
CoreBluetooth for Swift: Complete Guide with Examples
Sending SMS in C# (.NET): Integration with SMS Service APIs via HttpClient