Data Validation in C# (.NET): Libraries, Attributes, and FluentValidation

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

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 be null or 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.AspNetCore


Example 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

Recommendations