Data Annotation Attributes in ASP.NET Core MVC

Data Annotation Attributes in ASP.NET Core MVC

In this article, I will discuss How to Perform Model Validations using Data Annotation Attributes in the ASP.NET Core MVC Application with Examples. Please read our previous article discussing Model Validations in ASP.NET Core MVC.

Built-in Data Annotation Attributes

ASP.NET Core MVC Provides many built-in Data Annotation Attributes for Model Validation as follows. These Data Annotation Attributes belong to the System.ComponentModel.DataAnnotations namespace.

  • [Required]: The Required attribute is used to mark a property as mandatory. 
  • [MinLength(length)] and [MaxLength(length)]: These two Data Annotation Attributes specify the maximum and minimum lengths for a string property, respectively.
  • [StringLength(maxLength, MinimumLength = minLength)]: This Attribute sets the maximum length of a string property and optional minimum length. 
  • [Range(min, max)]: This attribute restricts a property to a certain range of values. It is applicable to numerical data where you need to set minimum and maximum values.
  • [EmailAddress]: This attribute checks a property has a valid email format.
  • [RegularExpression(pattern)]: This attribute ensures that the property value matches a specified regular expression, which is useful for validating formats like phone numbers, zip codes, email formats, etc.
  • [Compare(“OtherProperty”)]: This attribute compares two properties of a model. It is often used to confirm passwords, emails, and other fields that require verification. 
  • [DataType(type)]: This Data Annotation Attribute specifies the type of data, such as Date, URL, Phone, CreditCard, Time, Email Address, etc. 

Let us understand the above Attributes by taking one real-time example. At the end of this article, we will create the following Employee Creation Form with Proper Validation both at the Client and Server Side using the Built-in Data Annotation Attributes of ASP.NET Core MVC Framework.

Data Annotation Attributes in ASP.NET Core MVC

Required Data Annotation Attribute in ASP.NET Core MVC

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.  In the ASP.NET Core MVC application, we can achieve this very easily by decorating the FirstName and LastName model properties with the Required Data Annotation attribute. The Required attribute makes the model property as required. For a better understanding, please look at the following Employee Model:

using System.ComponentModel.DataAnnotations;
namespace DataAnnotationsDemo.Models
{
    public class Employee
    {
        [Required]
        public string FirstName { get; set; }
        [Required]
        public string LastName { get; set; }
    }
}
Using the Model Inside a Controller:

Let us use the Employee model inside a Controller. So, modify the Employee Controller as follows. The GET version of the Create action method will render the view where it will ask the user to submit the form with First and Last Name values. Once the form is submitted, it will submit the form data to the Post version of the Create action method. Here, we are using ModelState.IsValid property to check whether the Model state is valid or not. If valid, we process the request and navigate to the Successful page, and if not, then we stay in the same view by displaying the Model Validation error messages.

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";
        }
    }
}
Using the Model Inside a View with Validation:

Let us use the Employee model inside the Create.cshtml view. So, 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. When we submit the page without providing an employee’s first and last name, we will get the error message as shown in the image below.

Required Data Annotation Attribute in ASP.NET Core MVC

With the Required Data Annotation 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. For a better understanding, please modify the Employee class as follows:

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.

How to Perform Model Validations using Data Annotation Attributes in ASP.NET Core MVC Application with Examples

StringLength Data Annotation Attribute in ASP.NET Core MVC

In our last example, we are forcing the user to enter his first and last names, but what happens if he enters an enormously long name? For example, our business requirement is that the employee’s last name should not be more 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, you cannot enter more than 30 characters in the Last Name text box, as shown in the image below. 

StringLength Data Annotation Attribute in ASP.NET Core MVC

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 the property as required, use the [Required] attribute and the [StringLength] attribute. That means it is also possible to 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.

How to Perform Model Validations using Data Annotation Attributes in ASP.NET Core MVC Application with Examples

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. So, modify the Employee model as follows:

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 field is a required field and will validate whether the field value is a proper email ID format or not, 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.

RegularExpression Data Annotation Attribute in ASP.NET Core MVC

User Name Validation Example using Regular Expression:

Here is the requirement for validating the User Name property in our application:

  • User Name 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 easily achieved in ASP.NET Core MVC using Regular Expression Attributes. 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.

How to Perform Model Validations using Data Annotation Attributes in ASP.NET Core MVC Application with Examples

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, we can enter any value, such as 5000 as the age and click on the Submit button, and then the data will also be saved.

As we know, an employee who is 5000 years old 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 an 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:

Range Data Annotation Attribute in ASP.NET Core MVC

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.

MinLength and MaxLength Attribute in ASP.NET Core MVC

DataType Attribute in ASP.NET Core MVC:

The DataType Attribute in the ASP.NET Core MVC Framework enables us to provide 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, Phone Number, Credit Card, 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.

DataType Attribute in ASP.NET Core MVC

Let’s see an example of using the DataType attribute in the ASP.NET Core MVC Application. Please modify the Employee model class as follows. Here, we are using the DataType attribute to validate the Postal Code, Website URL, Password, Mobile Number, Email Address, and Salary of an employee.

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:

The Compare Data Annotation Attribute in ASP.NET Core MVC Framework compares 2 model properties with the same value. The Compare attribute is commonly used to compare credit card numbers and passwords. 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:

Compare Data Annotation Attribute in ASP.NET MVC Application

Real-Time Example:

Let us see one real-time example of understanding the data annotation attributes in an ASP.NET core MVC application. We will be creating an Employee form to create a new employee with proper validation both on the client and server sides. So, first, create a class file named Gender.cs and then copy and paste the following code. This is going to be an enum containing the gender-named constants.

namespace DataAnnotationsDemo.Models
{
    public enum Gender
    {
        Male,
        Female
    }
}
Employee Model:

Next, 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 = "Please Select the Department")]
        public string Department { 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; }

        [Required(ErrorMessage = "Please Select the Gender")]
        public Gender Gender { 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; }

        //True means permanent and false means contractual
        public bool IsPermanent { get; set; }
        [Required(ErrorMessage = "Date of Joining is required")]
        [DataType(DataType.Date, ErrorMessage = "Invalid Date Format")]
        public DateTime DateOfJoining { get; set; }

        public List<string> SkillSets { get; set; } = new List<string>();

        [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; }
    }
}
Employee Controller:

Next, modify the Employee Controller as follows:

using DataAnnotationsDemo.Models;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Rendering;

namespace DataAnnotationsDemo.Controllers
{
    public class EmployeeController : Controller
    {
        public IActionResult Create()
        {
            PrepareEmployeeViewModel();
            return View();
        }

        [HttpPost]
        public IActionResult Create(Employee employee)
        {
            if (ModelState.IsValid)
            {
                //Save the Data into the Database
                //Redirect to a Different View
                return RedirectToAction("Successful");
            }

            PrepareEmployeeViewModel();
            return View(employee);
        }

        public string Successful()
        {
            return "Employee Added Successfully";
        }

        private void PrepareEmployeeViewModel()
        {
            ViewBag.AllGenders = Enum.GetValues(typeof(Gender)).Cast<Gender>().ToList();
            ViewBag.Departments = GetDepartments();
            ViewBag.SkillSets = new List<string> { "Dot Net", "Java", "Python", "PHP", "Database" };
        }

        private List<SelectListItem> GetDepartments()
        {
            //You can get the data from the database and populate the SelectListItem
            return new List<SelectListItem>()
            {
                new SelectListItem { Text = "IT", Value = "1" },
                new SelectListItem { Text = "HR", Value = "2" },
                new SelectListItem { Text = "Payroll", Value = "3" },
                new SelectListItem { Text = "Admin", Value = "4" }
            };
        }
    }
}
Employee Create View:

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="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="Department" class="col-sm-2 col-form-label"></label>
            <div class="col-sm-10">
                <select asp-for="Department" class="form-select"
                        asp-items="ViewBag.Departments">
                    <option value="">Please Select</option>
                </select>
                <span asp-validation-for="Department" 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" type="number">
                <span asp-validation-for="Age" class="text-danger"></span>
            </div>
        </div>

        <div class="form-group row">
            <label asp-for="IsPermanent" class="col-sm-2 col-form-label"></label>
            <div class="col-sm-10">
                <input asp-for="IsPermanent" class="custom-control-input">
            </div>
        </div>
        
        <div class="form-group row">
            <label asp-for="Gender" class="col-sm-2 col-form-label"></label>
            <div class="col-sm-10">
                @foreach (var gender in ViewBag.AllGenders)
                {
                    <label class="radio-inline">
                        <input type="radio" asp-for="Gender" value="@gender" id="Gender@(gender)" />@gender<br />
                    </label>
                }
                <span asp-validation-for="Gender" 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" type="url" class="form-control" placeholder="Please Endter 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" type="number" 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="DateOfJoining" class="col-sm-2 col-form-label"></label>
            <div class="col-sm-10">
                <input asp-for="DateOfJoining" class="form-control" placeholder="Please Enter Your UserName/LoginName">
                <span asp-validation-for="DateOfJoining" class="text-danger"></span>
            </div>
        </div>
        <div class="form-group row">
            <label asp-for="SkillSets" class="col-sm-2 col-form-label"></label>
            <div class="col-sm-10">
                <style>
                    .form-check {
                        display: inline-block;
                        margin-right: 20px;
                    }
                </style>
                <div class="hobby-list" style="display: flex; flex-wrap: wrap;">
                    @{
                        int counter = 0;
                        foreach (var skill in ViewBag.SkillSets as List<string>)
                        {
                            <div class="form-check">
                                <label class="form-check-label" for="@("hobby" + counter)">@skill</label>
                                <input class="form-check-input" type="checkbox" name="SkillSets" value="@skill" id="@("skill" + ++counter)" />
                            </div>
                        }
                    }
                </div>
            </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>
@section Scripts {
    @{
        await Html.RenderPartialAsync("_ValidationScriptsPartial");
    }
}

With the above changes in place, run the application and test it, and it should work as expected. Here, in the DateOfJoining property, we have applied a built-in Attribute to ensure the date is required and format it correctly as a date. But if you want to enforce the date of joining, it should not be a future date; you need to create a custom validation attribute, which we will discuss in our next article.

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.

Leave a Reply

Your email address will not be published. Required fields are marked *