Back to: ASP.NET Core Tutorials For Beginners and Professionals
Data Annotation Attributes in ASP.NET Core MVC
In this article, I will discuss How to Perform Model Validations using Data Annotation Attributes in ASP.NET Core MVC Application with Examples. Please read our previous article discussing Model Validations in ASP.NET Core MVC.
Required Data Annotation Attribute in ASP.NET Core MVC
Let’s understand the Required Data Annotation Attribute with one example. Our business requirement is that an employee’s First Name and Last Name can’t be empty. That means we will force the user to give the first and last names; we can achieve this very easily in the ASP.NET Core MVC application by decorating the FirstName and LastName model properties with the Required data annotation attribute. The Required attribute makes the model property as required.
using System.ComponentModel.DataAnnotations; namespace DataAnnotationsDemo.Models { public class Employee { [Required] public string FirstName { get; set; } [Required] public string LastName { get; set; } } }
Next, modify the Employee Controller as follows:
using DataAnnotationsDemo.Models; using Microsoft.AspNetCore.Mvc; namespace DataAnnotationsDemo.Controllers { public class EmployeeController : Controller { public IActionResult Create() { return View(); } [HttpPost] public IActionResult Create(Employee employee) { //Check if the Model State is Valid if (ModelState.IsValid) { //Save the Data into the Database //Redirect to a Different View return RedirectToAction("Successful"); } //Return to the same View and Display Model Validation error return View(); } public string Successful() { return "Employee Added Successfully"; } } }
Next, modify the Create.cshtml view as follows:
@model DataAnnotationsDemo.Models.Employee @{ ViewData["Title"] = "Create"; } <h1>Create Employee</h1> <div class="row"> <form asp-controller="Employee" asp-action="Create" method="post" class="mt-3"> @*<div asp-validation-summary="All" class="text-danger"></div>*@ <div class="form-group row"> <label asp-for="FirstName" class="col-sm-2 col-form-label"></label> <div class="col-sm-10"> <input asp-for="FirstName" class="form-control" placeholder="Enter Your First Name"> <span asp-validation-for="FirstName" class="text-danger"></span> </div> </div> <div class="form-group row"> <label asp-for="LastName" class="col-sm-2 col-form-label"></label> <div class="col-sm-10"> <input asp-for="LastName" class="form-control" placeholder="Enter Your Last Name"> <span asp-validation-for="LastName" class="text-danger"></span> </div> </div> <div class="form-group row"> <div class="col-sm-10"> <button type="submit" class="btn btn-primary">Create</button> </div> </div> </form> </div>
The Required attribute raises a validation error if the property value is null or empty. The built-in required validation attributes provide both client-side and server-side validation. When we submit the page without providing the first name and last name of an employee, we will get the error message as shown in the below image.
With the required attributes in place, if someone tries to submit the page without providing the FirstName and LastName values, it will give us the default error, as shown in the above image. But suppose you want to provide some user-defined error message when validation fails. In that case, you can use the other overloaded version of the Required attribute, which accepts ErrorMessage as an input parameter, as shown below.
using System.ComponentModel.DataAnnotations; namespace DataAnnotationsDemo.Models { public class Employee { [Required(ErrorMessage = "First Name is Required")] public string FirstName { get; set; } [Required(ErrorMessage = "Last Name is Required")] public string LastName { get; set; } } }
With the above changes, if someone tries to submit the page without providing the FirstName and LastName values, it will give the user-defined error message, as shown in the image below.
StringLength Data Annotation Attribute in ASP.NET Core MVC
In our last example, we are forcing the user to enter his first name and last but what happens if he enters a name with enormous length? For example, our business requirement is that the employee’s last name should not be greater than 30 characters, which means we need to set a maximum of 30 characters that can be entered for the employee’s last name. We can easily achieve this using the StringLength data annotation attribute in the ASP.NET Core MVC application. To achieve this, we must decorate the LastName property with the StringLength attribute, as shown below.
using System.ComponentModel.DataAnnotations; namespace DataAnnotationsDemo.Models { public class Employee { [Required(ErrorMessage = "First Name is Required")] public string FirstName { get; set; } [Required(ErrorMessage = "Last Name is Required")] [StringLength(30)] public string LastName { get; set; } } }
With the above changes in place, it will not allow you to enter more than 30 characters in the Last Name text box, as shown in the below image.
The [StringLength] attribute verifies that a string is of a certain length but does not enforce that the property is REQUIRED. If you want to enforce that the property is required, use the [Required] attribute.
We can also apply multiple validation attributes on a single property. The MinimumLength is an optional named parameter used to specify a string’s minimum length. We can also specify the user-defined error message. Here, we specify the minimum length as 4 and the ErrorMessage as the Last name should be between 4 and 30 characters.
using System.ComponentModel.DataAnnotations; namespace DataAnnotationsDemo.Models { public class Employee { [Required(ErrorMessage = "First Name is Required")] public string FirstName { get; set; } [Required(ErrorMessage = "Last Name is Required")] [StringLength(30, MinimumLength = 4, ErrorMessage = "Last name should be between 4 and 30 characters")] public string LastName { get; set; } } }
In the above example, we have decorated the LastName property with the StringLength attribute and then specified the Minimum and Maximum length of the model properties. We also used the [Required] attribute. So, at this point, the LastName property is required and should be between 4 and 30 characters. Now run the application and check everything is working as expected, as shown below.
RegularExpression Data Annotation Attribute in ASP.NET Core MVC:
The Regular Expression Attribute is generally used for pattern-matching validations in ASP.NET Core MVC applications. Let’s understand the Regular expression attribute with an example. Suppose we need to validate the Email ID of an employee; then we can achieve this very easily in the ASP.NET MVC application by using Regular expression attributes as shown below:
using System.ComponentModel.DataAnnotations; namespace DataAnnotationsDemo.Models { public class Employee { [Required(ErrorMessage = "Email id is required")] [RegularExpression(@"^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$", ErrorMessage = "Please Enter a Valid Email")] public string EmailId { get; set; } } }
Next, modify the Create.cshtml view as follows.
@model DataAnnotationsDemo.Models.Employee @{ ViewData["Title"] = "Create"; } <h1>Create Employee</h1> <div class="row"> <form asp-controller="Employee" asp-action="Create" method="post" class="mt-3"> @*<div asp-validation-summary="All" class="text-danger"></div>*@ <div class="form-group row"> <label asp-for="EmailId" class="col-sm-2 col-form-label"></label> <div class="col-sm-10"> <input asp-for="EmailId" class="form-control" placeholder="Enter Your Email Id"> <span asp-validation-for="EmailId" class="text-danger"></span> </div> </div> <div class="form-group row"> <div class="col-sm-10"> <button type="submit" class="btn btn-primary">Create</button> </div> </div> </form> </div>
In the above example, we are applying both Required and RegularExpression attributes to the EmailID model property, which ensures that the Email ID is a required field and will validate the Email ID field value, as shown below. When a user tries to enter an invalid Email ID and submit the page, he will get the validation error message as shown below.
User Name Validation Example:
Here is the requirement for validating the Name property
- UserName can contain the first and last names with a single space.
- The last name is optional. If the last name is absent, there shouldn’t be any space after the first name.
- Only upper and lower-case alphabets are allowed.
This requirement can be achieved very easily in ASP.NET Core MVC using RegularExpressionAttribute. In the Employee.cs class file, decorate the UserName property with the RegularExpression attribute as shown below.
using System.ComponentModel.DataAnnotations; namespace DataAnnotationsDemo.Models { public class Employee { [Required(ErrorMessage = "UserName is required")] [RegularExpression(@"^(([A-za-z]+[\s]{1}[A-za-z]+)|([A-Za-z]+))$", ErrorMessage = "UserName can contain the first and last names with a single space. " + "The last name is optional. Only upper and lower case alphabets are allowed")] public string UserName { get; set; } [Required(ErrorMessage = "Email id is required")] [RegularExpression(@"^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$", ErrorMessage = "Please Enter a Valid Email")] public string EmailId { get; set; } } }
Notice that we are passing a regular expression string to the Attribute constructor. The Regular Expression Attribute is great for pattern matching and ensures that the value for the UserName property is in the format we want. Also, we use a verbatim literal (@ symbol) string, as we don’t want escape sequences to be processed. Next, modify the Create.cshtml file as follows.
@model DataAnnotationsDemo.Models.Employee @{ ViewData["Title"] = "Create"; } <h1>Create Employee</h1> <div class="row"> <form asp-controller="Employee" asp-action="Create" method="post" class="mt-3"> <div class="form-group row"> <label asp-for="UserName" class="col-sm-2 col-form-label"></label> <div class="col-sm-10"> <input asp-for="UserName" class="form-control" placeholder="Please Enter User Name"> <span asp-validation-for="UserName" class="text-danger"></span> </div> </div> <div class="form-group row"> <label asp-for="EmailId" class="col-sm-2 col-form-label"></label> <div class="col-sm-10"> <input asp-for="EmailId" class="form-control" placeholder="Enter Your Email Id"> <span asp-validation-for="EmailId" class="text-danger"></span> </div> </div> <div class="form-group row"> <div class="col-sm-10"> <button type="submit" class="btn btn-primary">Create</button> </div> </div> </form> </div>
Run the application and see the UserName field is working as expected.
Understanding and writing regular expressions is beyond the scope of this article. If you are interested in learning to write regular expressions, here is a link from MSDN
http://msdn.microsoft.com/en-us/library/az24scfc.aspx
Range Data Annotation Attribute in ASP.NET Core MVC:
Suppose we have the Age field in the Employee model. If we don’t provide any validations, then we can enter any value, such as 5000, as the age, and click on the Save button, then the data also gets saved.
As we know, an employee 5000 years of age is not possible. So, let’s validate the Age field and force users to enter a value between 18 and 60. We can achieve this easily using the RangeAttribute in ASP.NET Core MVC Application. The Range attributes specify a numerical number’s minimum and maximum constraints, as shown below.
using System.ComponentModel.DataAnnotations; namespace DataAnnotationsDemo.Models { public class Employee { [Required(ErrorMessage ="Age is Required")] [Range(18, 60, ErrorMessage = "Age must be between 18 and 60")] public int Age { get; set; } } }
In the above example, we set the employee’s age to be between 18 and 60 years to pass the validation. Here, the first parameter of the attribute is the minimum value, the second parameter is the maximum value, and the third parameter is the error message we want to show when the validation fails. Next, modify the Create.cshtml view as follows:
@model DataAnnotationsDemo.Models.Employee @{ ViewData["Title"] = "Create"; } <h1>Create Employee</h1> <div class="row"> <form asp-controller="Employee" asp-action="Create" method="post" class="mt-3"> <div class="form-group row"> <label asp-for="Age" class="col-sm-2 col-form-label"></label> <div class="col-sm-10"> <input asp-for="Age" class="form-control" placeholder="Please Enter Your Age"> <span asp-validation-for="Age" class="text-danger"></span> </div> </div> <div class="form-group row"> <div class="col-sm-10"> <button type="submit" class="btn btn-primary">Create</button> </div> </div> </form> </div>
When a user tries to enter the age which is not between 18 and 60 and clicks on the submit button, then he will get the validation error message as shown below:
At this point, we should not be able to enter any values outside the range of 18 and 60 for the Age field.
Note: The Range attribute in ASP.NET Core MVC does not support the validation of the DateTime fields.
MinLength and MaxLength Attribute in ASP.NET Core MVC:
These two attributes specify the Minimum and Maximum Length of a property. For example, suppose we want to restrict the Employee Address as 5 as the minimum length and 25 as the maximum length. In that case, we can decorate the address property with the MinLength and Maxlength attributes, as shown below.
using System.ComponentModel.DataAnnotations; namespace DataAnnotationsDemo.Models { public class Employee { [MinLength(5, ErrorMessage = "The Address must be at least 5 characters")] [MaxLength(25, ErrorMessage = "The Address cannot be more than 25 characters")] public string Address { get; set; } } }
Next, modify the Create.cshtml file as follows.
@model DataAnnotationsDemo.Models.Employee @{ ViewData["Title"] = "Create"; } <h1>Create Employee</h1> <div class="row"> <form asp-controller="Employee" asp-action="Create" method="post" class="mt-3"> <div class="form-group row"> <label asp-for="Address" class="col-sm-2 col-form-label"></label> <div class="col-sm-10"> <input asp-for="Address" class="form-control" placeholder="Please Enter Your Address"> <span asp-validation-for="Address" class="text-danger"></span> </div> </div> <div class="form-group row"> <div class="col-sm-10"> <button type="submit" class="btn btn-primary">Create</button> </div> </div> </form> </div>
Submitting the page by entering less than 5 characters will give the error as shown below.
DataType Attribute in ASP.NET Core MVC:
DataType Attribute in ASP.NET Core MVC Framework enables us to provide the runtime information about the specific purpose of the properties. For example, a property of type string can have various scenarios, as it might hold an Email address, URL, or password. Data types include Currency, URL, Phone, Date, Time, Password, etc. If you go to the definition of DataType Enum, you will see the following named constants that we can specify using the DataType Attribute.
Let’s see examples of using the DataType attribute in the ASP.NET Core MVC Application. Please modify the Employee model class as follows.
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; namespace DataAnnotationsDemo.Models { public class Employee { [DataType(DataType.PostalCode, ErrorMessage = "Please Enter a Valid PIN/ZIP Code")] public string PostalCode { get; set; } [DataType(DataType.Url, ErrorMessage = "Please Enter a Valid URL")] public string WebsiteURL { get; set; } [DataType(DataType.Password, ErrorMessage = "Please Enter Password")] public string Password { get; set; } [DataType(DataType.PhoneNumber, ErrorMessage = "Please Enter a Valid Phone Number")] public string Mobile { get; set; } [DataType(DataType.EmailAddress, ErrorMessage = "Please Enter a valid Email Address")] public string Email { get; set; } [Range(10000, 1000000, ErrorMessage = "Please Enter a Value Between 10000 and 1000000")] [DataType(DataType.Currency)] [Column(TypeName = "decimal(18, 2)")] public decimal Salary { get; set; } } }
Next, modify the Create.cshtml view as follows.
@model DataAnnotationsDemo.Models.Employee @{ ViewData["Title"] = "Create"; } <h1>Create Employee</h1> <div class="row"> <form asp-controller="Employee" asp-action="Create" method="post" class="mt-3"> <div class="form-group row"> <label asp-for="PostalCode" class="col-sm-2 col-form-label"></label> <div class="col-sm-10"> <input asp-for="PostalCode" class="form-control" placeholder="Please Enter Your Postal Code"> <span asp-validation-for="PostalCode" class="text-danger"></span> </div> </div> <div class="form-group row"> <label asp-for="WebsiteURL" class="col-sm-2 col-form-label"></label> <div class="col-sm-10"> <input asp-for="WebsiteURL" class="form-control" placeholder="Please Enter Your Website URL"> <span asp-validation-for="WebsiteURL" class="text-danger"></span> </div> </div> <div class="form-group row"> <label asp-for="Password" class="col-sm-2 col-form-label"></label> <div class="col-sm-10"> <input asp-for="Password" class="form-control" placeholder="Please Enter Your Password"> <span asp-validation-for="Password" class="text-danger"></span> </div> </div> <div class="form-group row"> <label asp-for="Mobile" class="col-sm-2 col-form-label"></label> <div class="col-sm-10"> <input asp-for="Mobile" class="form-control" placeholder="Please Enter Your Mobile Number"> <span asp-validation-for="Mobile" class="text-danger"></span> </div> </div> <div class="form-group row"> <label asp-for="Email" class="col-sm-2 col-form-label"></label> <div class="col-sm-10"> <input asp-for="Email" class="form-control" placeholder="Please Enter Your Email Address"> <span asp-validation-for="Email" class="text-danger"></span> </div> </div> <div class="form-group row"> <label asp-for="Salary" class="col-sm-2 col-form-label"></label> <div class="col-sm-10"> <input asp-for="Salary" class="form-control" placeholder="Please Enter Your Salary"> <span asp-validation-for="Salary" class="text-danger"></span> </div> </div> <div class="form-group row"> <div class="col-sm-10"> <button type="submit" class="btn btn-primary">Create</button> </div> </div> </form> </div>
Compare Data Annotation Attribute in ASP.NET MVC Application:
Compare Attribute in ASP.NET Core MVC Framework is used to compare 2 model properties with the same value. Comparing credit card numbers and passwords is the common use case of the Compare attribute. Let’s understand using the Compare attribute with an example. For example, to ensure that the user has typed the correct password, we must use the Password and ConfirmPassword of the employee model, as shown below.
using System.ComponentModel.DataAnnotations; namespace DataAnnotationsDemo.Models { public class Employee { [DataType(DataType.Password)] [Required(ErrorMessage = "Password is Required")] public string Password { get; set; } [DataType(DataType.Password)] [Required(ErrorMessage = "Confirm Password is Required")] [Compare("Password", ErrorMessage = "Password and Confirm Password do not match")] public string ConfirmPassword { get; set; } } }
Next, modify the Create.cshtml view as follows.
@model DataAnnotationsDemo.Models.Employee @{ ViewData["Title"] = "Create"; } <h1>Create Employee</h1> <div class="row"> <form asp-controller="Employee" asp-action="Create" method="post" class="mt-3"> <div class="form-group row"> <label asp-for="Password" class="col-sm-2 col-form-label"></label> <div class="col-sm-10"> <input asp-for="Password" class="form-control" placeholder="Please Enter Your Password"> <span asp-validation-for="Password" class="text-danger"></span> </div> </div> <div class="form-group row"> <label asp-for="ConfirmPassword" class="col-sm-2 col-form-label"></label> <div class="col-sm-10"> <input asp-for="ConfirmPassword" class="form-control" placeholder="Please Confirm Your Password"> <span asp-validation-for="ConfirmPassword" class="text-danger"></span> </div> </div> <div class="form-group row"> <div class="col-sm-10"> <button type="submit" class="btn btn-primary">Create</button> </div> </div> </form> </div>
Now, if both Password and Confirm Password are not the same, the user will get the model validation error, as shown below:
Complete Example:
Let us put all the validation into a single model. So, modify the Employee.cs class file as follows.
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; namespace DataAnnotationsDemo.Models { public class Employee { [Required(ErrorMessage = "First Name is Required")] [StringLength(30, MinimumLength = 5, ErrorMessage = "First name should be between 5 and 30 characters")] public string FirstName { get; set; } [Required(ErrorMessage = "Last Name is Required")] [StringLength(30, ErrorMessage ="Maximum 30 Characters allowed")] public string LastName { get; set; } [Required(ErrorMessage = "UserName is required")] [RegularExpression(@"^(([A-za-z]+[\s]{1}[A-za-z]+)|([A-Za-z]+))$", ErrorMessage = "UserName can contain the first and last names with a single space. " + "The last name is optional. Only upper and lower case alphabets are allowed")] public string UserName { get; set; } [Required(ErrorMessage = "Email id is required")] [DataType(DataType.EmailAddress, ErrorMessage = "Please Enter a valid Email Address")] public string EmailId { get; set; } [Required(ErrorMessage = "Age is Required")] [Range(18, 60, ErrorMessage = "Age must be between 18 and 60")] public int Age { get; set; } [MinLength(5, ErrorMessage = "The Address must be at least 5 characters")] [MaxLength(50, ErrorMessage = "The Address cannot be more than 50 characters")] public string Address { get; set; } [DataType(DataType.Url, ErrorMessage = "Please Enter a Valid URL")] public string WebsiteURL { get; set; } [Range(10000, 1000000, ErrorMessage = "Please Enter a Value Between 10000 and 1000000")] [DataType(DataType.Currency)] [Column(TypeName = "decimal(18, 2)")] public decimal Salary { get; set; } [DataType(DataType.Password)] [Required(ErrorMessage = "Password is Required")] public string Password { get; set; } [DataType(DataType.Password)] [Required(ErrorMessage = "Confirm Password is Required")] [Compare("Password", ErrorMessage = "Password and Confirm Password do not match")] public string ConfirmPassword { get; set; } } }
Create.cshtml:
@model DataAnnotationsDemo.Models.Employee @{ ViewData["Title"] = "Create"; } <h1>Create Employee</h1> <div class="row"> <form asp-controller="Employee" asp-action="Create" method="post" class="mt-3"> <div class="form-group row"> <label asp-for="FirstName" class="col-sm-2 col-form-label"></label> <div class="col-sm-10"> <input asp-for="FirstName" class="form-control" placeholder="Please Enter Your FirstName"> <span asp-validation-for="FirstName" class="text-danger"></span> </div> </div> <div class="form-group row"> <label asp-for="LastName" class="col-sm-2 col-form-label"></label> <div class="col-sm-10"> <input asp-for="LastName" class="form-control" placeholder="Please Enter Your LastName"> <span asp-validation-for="LastName" class="text-danger"></span> </div> </div> <div class="form-group row"> <label asp-for="UserName" class="col-sm-2 col-form-label"></label> <div class="col-sm-10"> <input asp-for="UserName" class="form-control" placeholder="Please Enter Your UserName/LoginName"> <span asp-validation-for="UserName" class="text-danger"></span> </div> </div> <div class="form-group row"> <label asp-for="EmailId" class="col-sm-2 col-form-label"></label> <div class="col-sm-10"> <input asp-for="EmailId" class="form-control" placeholder="Please Enter Your EmailId"> <span asp-validation-for="EmailId" class="text-danger"></span> </div> </div> <div class="form-group row"> <label asp-for="Age" class="col-sm-2 col-form-label"></label> <div class="col-sm-10"> <input asp-for="Age" class="form-control" placeholder="Please Enter Your Age"> <span asp-validation-for="Age" class="text-danger"></span> </div> </div> <div class="form-group row"> <label asp-for="Address" class="col-sm-2 col-form-label"></label> <div class="col-sm-10"> <input asp-for="Address" class="form-control" placeholder="Please Enter Your Address"> <span asp-validation-for="Address" class="text-danger"></span> </div> </div> <div class="form-group row"> <label asp-for="WebsiteURL" class="col-sm-2 col-form-label"></label> <div class="col-sm-10"> <input asp-for="WebsiteURL" class="form-control" placeholder="Please Confirm Your Website URL"> <span asp-validation-for="WebsiteURL" class="text-danger"></span> </div> </div> <div class="form-group row"> <label asp-for="Salary" class="col-sm-2 col-form-label"></label> <div class="col-sm-10"> <input asp-for="Salary" class="form-control" placeholder="Please Confirm Your Salary"> <span asp-validation-for="Salary" class="text-danger"></span> </div> </div> <div class="form-group row"> <label asp-for="Password" class="col-sm-2 col-form-label"></label> <div class="col-sm-10"> <input asp-for="Password" class="form-control" placeholder="Please Enter Your Password"> <span asp-validation-for="Password" class="text-danger"></span> </div> </div> <div class="form-group row"> <label asp-for="ConfirmPassword" class="col-sm-2 col-form-label"></label> <div class="col-sm-10"> <input asp-for="ConfirmPassword" class="form-control" placeholder="Please Confirm Your Password"> <span asp-validation-for="ConfirmPassword" class="text-danger"></span> </div> </div> <div class="form-group row"> <div class="col-sm-10"> <button type="submit" class="btn btn-primary">Create</button> </div> </div> </form> </div>
In the next article, I will discuss How to Create Custom Data Annotations in ASP.NET Core MVC Applications with Real-Time Examples. In this article, I try to explain Data Annotation Attributes in ASP.NET Core MVC with Examples. I hope you enjoy this Data Annotation Attributes in ASP.NET Core MVC article.