- Home
- .NET tutorials
- Data Annotations for model validation in ASP.NET Core
Data Annotations for model validation in ASP.NET Core
Published: Friday 24 February 2023
Default Data Annotation validators
System.ComponentModel.DataAnnotations assembly, and they provide attribute classes that can be used for validating a model property.
Required- Ensures that the property has a value assigned to itEmailAddress- Validates the format of an email addressRegularExpression- Validates the format of a particular value using regular expressionMinLength- The minimum length of a valueMaxLength- The maximum length of a value
How to use Data Annotation validators
Create endpoint. Within that, an instance the CustomerModel type has been passed in as a parameter.
// CustomerController.cs
[ApiController]
[Route("api/[controller]")]
public class CustomerController : ControllerBase
{
[HttpPost]
public IActionResult Create(CustomerModel customerModel)
{
return Ok(customerModel);
}
}
CustomerModel class has a number of properties that represent data fields for the customer.
public class CustomerModel
{
[Required, MinLength(3), MaxLength(30)]
public string? FirstName { get; init; }
[Required, MinLength(3), MaxLength(50)]
public string? Surname { get; init; }
[EmailAddress]
public string? Email { get; init; }
[RegularExpression("^([0-9]{5})$")]
public string? ZipCode { get; init; }
}
In the above example, the following must all be met for the model to validate:
- First name - Is required, and has a length of between 3 and 30 characters
- Surname - Is required, and has a length of between 3 and 50 characters
- Email - Must be a valid email address
- Zip code - Must match the regular expression which states that it has to have five numbers as it's value
When running the ASP.NET Core Web API and calling this endpoint, if some of the properties have not been validated against their data annotation attributes, the Web API returns a 400 response and lists all the different errors as part of it.
Sending a POST request in an ASP.NET Core Web API
A 400 response is returned when not all validators are passed
It's only when all the properties are successfully validated does the Web API return with a valid response.
Creating a custom validator
In-addition to the validators contained in the System.ComponentModel.DataAnnotations assembly, custom Data Annotation validators can be created. This is great for more complex validation methods which are not contained in the .NET library.
ValidationAttribute abstract class. Within that, the IsValid method can be overridden.
IsValid method has two overrides. Both of them pass in a nullable object as a value. This represents the value of the property that is being validated.
ValidationContext type. This allows for getting the full object instance so if values need to be compared with different properties in the model. This also returns a ValidationResult type which allows for a custom error message to be returned.
// ValidationAttribute.cs
public virtual bool IsValid(object? value) {
...
}
protected virtual ValidationResult? IsValid(object? value, ValidationContext validationContext) {
...
}
Within that, the validation can be performed.
Required attribute can handle this.
DateTime type. If it can't be, an error message is displayed.
// CustomerDateOfBirthValidation.cs
public class CustomerDateOfBirthValidation : ValidationAttribute
{
public const string MINIMUM_DATE_OF_BIRTH = "The customer is younger than 18 years old";
/// <summary>
/// Minimum age
/// </summary>
private int minAge = 18;
/// <summary>
/// Whether the date of birth is valid.
/// </summary>
/// <param name="value"></param>
/// <returns></returns>
protected override ValidationResult? IsValid(object? value, ValidationContext validationContext)
{
var valueString = value != null ? value.ToString() : null;
if (string.IsNullOrWhiteSpace(valueString))
{
// No value, so return success.
return ValidationResult.Success;
}
// Convert to date time.
if (!DateTime.TryParse(valueString, out DateTime dob))
{
// Not a valid date, so return error.
return new ValidationResult("Unable to convert the date of birth to a valid date");
}
// Minimum date of birth
var minDateOfBirth = DateTime.Now.Date.AddYears(minAge * -1);
if (dob > minDateOfBirth)
{
// Under minimum date of birth, so return error.
return new ValidationResult(MINIMUM_DATE_OF_BIRTH);
}
// Return success
return ValidationResult.Success;
}
}
This can be applied to a property in the CustomerModel like this:
public class CustomerModel
{
...
[DataType(DataType.Date), Required, CustomerDateOfBirthValidation]
public DateTime? DateOfBirth { get; init; }
}
More information
Watch our video where we talk through Data Annotation validators in more depth, and show how they can work in an ASP.NET Core Web API.
In-addition, the code example that is used in this example can be downloaded.
Using it in MVC is much the same
This example shows how to use Data Annotation validators in an ASP.NET Core Web API, but it's much the same when using MVC. A model is created, and Data Annotation validators can be assigned to each property.
ApiController attribute in a controller, if a model does not meet the validation, it returns a 400 response with a list of all the errors. This would normally be used in an ASP.NET Core Web API.
ModelState instance can be called inside an action, and within that, there is an IsValid property. If this is set to false, the model has failed validation.
Related tutorials