liveBook · Manning

IValidatableObject

As explained in ASP.NET Core in Action, 3e

IValidatableObject is a .NET interface that lets an object perform validation involving its own property values and return validation results.

IValidatableObject lets a model validate relationships between its own property values when individual DataAnnotations attributes are not enough. Implement Validate and return ValidationResult objects describing any invalid combination. section 7.10.2

Listing 7.11 Implementing IValidatableObject
using System.ComponentModel.DataAnnotations;
 
public record CreateUserModel : IValidatableObject               #1
{
    [EmailAddress]                                               #2
    public string Email { get; set; }
 
    [Phone]                                                      #2
    public string PhoneNumber { get; set; }
 
    public IEnumerable<ValidationResult> Validate(               #3
        ValidationContext validationContext)                     #3
    {
        if(string.IsNullOrEmpty(Email)                           #4
            && string.IsNullOrEmpty(PhoneNumber))                #4
        {
            yield return new ValidationResult(                   #5
                "You must provide an Email or a PhoneNumber",    #5
                New[] { nameof(Email), nameof(PhoneNumber) });   #5
        }
    }
}
#1 Implements the IValidatableObject interface
#2 The DataAnnotation attributes continue to validate basic format requirements.
#3 Validate is the only function to implement in IValidatableObject.
#4 Checks whether the object is valid . . .
#5 . . . and if not, returns a result describing the error

Shows a CreateUserModel that combines Email and PhoneNumber attributes with a Validate method requiring at least one contact value. section 7.10.2

Use it with these practical boundaries:

  • Keep isolated property checks in DataAnnotations, such as email and phone formats; use IValidatableObject when validity depends on multiple properties. section 7.10.2
  • Return a ValidationResult with the error message and related property names, such as Email and PhoneNumber. section 7.10.2
  • Remember that Validate runs only after all DataAnnotations conditions pass and does not provide easy access to application services. section 7.10.2
  • Handle validation outcomes explicitly: Razor Pages runs validation after model binding, but the page handler still executes unless the application checks the result. section 16.3.1

How ASP.NET Core in Action, 3e covers it

How deep it goes
Explains interface implementation, ValidationResult creation, execution order, and service-access limitations without developing complex business validation.
Examples
Demonstrates requiring either an email address or phone number through a CreateUserModel Validate method.
What it assumes
Assumes familiarity with model properties and DataAnnotations while showing the interface pattern from its basic implementation.
What you can do after
Apply it by implementing Validate and returning property-linked ValidationResult objects for cross-property rules.
How it connects
Connects IValidatableObject with DataAnnotations, model binding, ValidationAttribute, Razor Pages, minimal APIs, and FluentValidation.

Also explained in

Compare how 2 books explain IValidatableObject →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of ASP.NET Core in Action, 3e. The section links point to the parts of the book it draws on.