ASP.NET Core’s built-in validation attributes cover a wide range of scenarios, you’ll inevitably encounter validation rules specific to your application’s business logic. Custom validation attributes, derived from the ValidationAttribute class, empower you to create these tailored validations.
Key Steps Inherit from ValidationAttribute: Create a class that inherits from ValidationAttribute. Override IsValid: The core of your custom validation logic lies in the IsValid method. This method receives the value to be validated and a ValidationContext object (containing additional information about the model). Return ValidationResult: If the value is valid, return ValidationResult.Success. If the value is invalid, return a new ValidationResult object with your custom error message.
Code public class DateRangeValidatorAttribute : ValidationAttribute { public string OtherPropertyName { get; set; }
// Constructor public DateRangeValidatorAttribute(string otherPropertyName) { OtherPropertyName = otherPropertyName; }
protected override ValidationResult? IsValid(object? value, ValidationContext validationContext) { if (value != null) { // Get the “to_date” DateTime toDate = Convert.ToDateTime(value);
// Get the “from_date” var otherProperty = validationContext.ObjectType.GetProperty(OtherPropertyName);
if (otherProperty != null) { DateTime fromDate = Convert.ToDateTime(otherProperty.GetValue(validationContext.ObjectInstance));
if (fromDate > toDate) { return new ValidationResult(ErrorMessage, new string[] { OtherPropertyName, validationContext.MemberName }); // Indicate the specific properties involved in the error } else { return ValidationResult.Success; } } return null; // Return null if otherProperty is null } return null; // Return null if value is null } }
Purpose: Ensures that a date (e.g., ToDate) is not earlier than another date (FromDate). OtherPropertyName: Specifies the name of the property to compare against (in this case, FromDate). IsValid: It retrieves the values of both properties using reflection. It compares the dates and returns an error message if toDate is earlier than fromDate. The error message includes the names of both properties, providing clear feedback to the user.
Example public class MinimumYearValidatorAttribute : ValidationAttribute { public int MinimumYear { get; set; } = 2000; public string DefaultErrorMessage { get; set; } = “Year should not be less than {0}”;
// … (constructors) …
protected override ValidationResult? IsValid(object? value, ValidationContext validationContext) { if (value != null) { DateTime date = (DateTime)value; if (date.Year >= MinimumYear) { return ValidationResult.Success; } else { return new ValidationResult(string.Format(ErrorMessage ?? DefaultErrorMessage, MinimumYear)); // Use custom or default error message } }
return null; } }
Purpose: Ensures that a date (e.g., DateOfBirth) is not earlier than a specified year. MinimumYear: Sets the minimum allowed year (defaulting to 2000). DefaultErrorMessage: Provides a default error message if a custom message isn’t provided. IsValid: It checks if the year of the given date is greater than or equal to the minimum year.