Implementation of Custom Server-Side Validation Rules in ASP.NET

We use validation attributes in ASP.NET Core to validate model properties. These validation attributes are available in System.ComponentModel.DataAnnotations namespace. Even if there are many built-in validation attributes, we will sometimes have to use custom validation attributes to enforce our business rules. This article explains how it can be done.

The first step to create a custom validation attribute is creating a class that inherits from ValidationAttribute class and overrides the IsValid method. The IsValid method accepts a parameter of type Object, which is the value of the object to validate. The IsValid method has an overloaded version that accepts an object of type ValidationContext, which contains details of the model instance on which the validation is performed. You can download the code related to this article from GitHub. 

The sample application with this article is a .NET 5.0 Razor Page application. I have a model class named Employee in the application with the following structure.

using CustomValidation.CustomValidators;
using Microsoft.AspNetCore.Mvc.Rendering;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;

namespace CustomValidation.Models
{
    public class Employee
    {
        public int Id { get; set; }
        [Required]
        public string Name { get; set; }

        [EmailAddress]
        [RequireContactDetails]
        public string Email { get; set; }

        [RegularExpression(@"^([0-9]{10})$", ErrorMessage = "Invalid Mobile Number.")]
        [RequireContactDetails]
        public string Mobile { get; set; }
        [InterviewDate(ErrorMessage = "Interview date must be greater than the current date")]
        [Display(Name = "Interview Date")]
        public DateTime InterviewDate { get; set; }

        [Display(Name = "Position")]
        public IList<SelectListItem> AppliedPosition { get; set; }
        [RequireExperiance]
        [Display(Name = "Experiance Details")]
        public string ExperianceDetails { get; set; }
        [Required]
        [Display(Name = "Position")]
        public string AppliedPositionName { get; set; }

    }
}

I have used three custom validation attributes to enforce my business logic. They are RequireContactDetails, RequireExperiance and InterviewDate

A mobile number or email Id is mandatory to submit the form. For that, I created the following RequireContactDetailsAttribute validation class.

using CustomValidation.Models;
using System.ComponentModel.DataAnnotations;
namespace CustomValidation.CustomValidators
{
    public class RequireContactDetailsAttribute : ValidationAttribute
    {
        protected override ValidationResult IsValid(object value, ValidationContext validationContext)
        {
            Employee employee = (Employee)validationContext.ObjectInstance;

            if (string.IsNullOrEmpty(employee.Email)  && string.IsNullOrEmpty(employee.Mobile))
            {
                return new ValidationResult("Please enter an email address or a mobile number");
            }

            return ValidationResult.Success;
        }
    }

}

 

The class is inherited from ValidationAttribute class and overrides the Isvalid method. We get the details of the Employee object from the validationContext parameter. The values of the email and mobile number fields are examined there, and if both are empty, a validation error is returned.

Another custom validation rule makes sure that the interview date is greater than the current date. For that, I created the following Custom validation class. This class returns false if the date selected is not greater than the current date. 

using System;
using System.ComponentModel.DataAnnotations;

namespace CustomValidation.CustomValidators
{
    public class InterviewDateAttribute:ValidationAttribute
    {
        public override bool IsValid(object value)
        {            
            return Convert.ToDateTime(value).Date > DateTime.Today;
        }
    }
}

The last custom validation rule is to make the experience details field mandatory for all designations, excluding “Trainee”. I created the following class for that. 

using System.ComponentModel.DataAnnotations;
using CustomValidation.Models;
namespace CustomValidation.CustomValidators
{
    public class RequireExperianceAttribute : ValidationAttribute
    {
        protected override ValidationResult IsValid(object value, ValidationContext validationContext)
        {
            Employee employee = (Employee)validationContext.ObjectInstance;

            if ((employee.AppliedPositionName.ToUpper() != "TRAINEE" && string.IsNullOrEmpty(employee.ExperianceDetails)))
            {
                return new ValidationResult("Please enter experiance details");
            }

            return ValidationResult.Success;
        }
    }
}

 

I created a form to accept the values for the Employee model. The following is the screenshot of the form with the custom validation errors. 

Implementation of custom validation in ASP.NET


Search