How to implement Custom user defined At Least One required Validation rules in MVC 4 application.

Introduction

In this post, How to implement Custom user defined At Least One required Validation rules in MVC 4 application.
There are many validation attributes available in MVC 4 like required, StringLength, Range, RegularExpression and more but sometimes we may require specific type of validation .In this article, I will explain how you can create your own custom validation attribute for At Least One required Validation
on and also how to make it work on client side as well.

Steps :

Step - 1 : Create New Project.

Go to File > New > Project > Select asp.net MVC4 web application > Entry Application Name > Click OK > Select Internet Application > Select view engine Razor > OK

Step-2: Add a Database.

Go to Solution Explorer > Right Click on App_Data folder > Add > New item > Select SQL Server Database Under Data > Enter Database name > Add.

Step-3: Create table for save  data.

Open Database > Right Click on Table > Add New Table > Add Columns > Save > Enter table name > Ok.
In this example, I have used one tables as below


Step-4: Add Entity Data Model.

Go to Solution Explorer > Right Click on Project name form Solution Explorer > Add > New item > Select ADO.net Entity Data Model under data > Enter model name > Add.
A popup window will come (Entity Data Model Wizard) > Select Generate from database > Next >
Chose your data connection > select your database > next > Select tables > enter Model Namespace > Finish.

Step-5: Add a new class for create custom validation rule.

write the following code in this class.
We need to import following namespace
            using System.ComponentModel.DataAnnotations;
            using System.Web.Mvc;
        
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace MVCCustomValidation
{
    public class AtLeastOneRequired : ValidationAttribute, IClientValidatable
    {
        public string OtherPropertyNames;
        
        /// <summary>
        /// 
        /// </summary>
        /// <param name="otherPropertyNames">Multiple property name with comma(,) separator</param>
        public AtLeastOneRequired(string otherPropertyNames)
        {
            OtherPropertyNames = otherPropertyNames;
        }

        protected override ValidationResult IsValid(object value, ValidationContext validationContext)
        {
            string[] propertyNames = OtherPropertyNames.Split(',');
            bool isAllNull = true;
            foreach (var i in propertyNames)
            {
                var p = validationContext.ObjectType.GetProperty(i);
                var val = p.GetValue(validationContext.ObjectInstance, null);
                if (val != null && val.ToString().Trim()!="")
                {
                    isAllNull = false;
                    break;
                }
            }

            if (isAllNull)
            {
                return new ValidationResult(FormatErrorMessage(validationContext.DisplayName));
            }
            else
            {
                return null;
            }
        }

        public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
        {
            var rules = new ModelClientValidationRule()
            {
                 ErrorMessage = FormatErrorMessage(metadata.DisplayName),
                  ValidationType = "atleastonerequired" // validation type should be lowercase
            };
            rules.ValidationParameters["otherpropertynames"] = OtherPropertyNames;
            yield return rules;
        }
    }
}

Step-6: Add a new js file for apply custom validation rule client side.

Go to Solution Explorer > Right Click on Controllers folder form Solution Explorer > Add > new item > select javascript file > Enter file name > Add.

write the following code in this js file.

// Here I will add code for client side validation for our custom validation (At Least One required Validation)

$.validator.unobtrusive.adapters.addSingleVal("atleastonerequired", "otherpropertynames");
$.validator.addMethod("atleastonerequired", function (value, element, params) {
    var param = params.toString().split(',');
    var isAllNull = true;
    $.each(param, function (i, val) {
        var valueOfItem = $('#' + val).val().trim();
        if (valueOfItem != '') {
            isAllNull = false;
            return false;
        }
    });
    if (isAllNull) {
        return false;
    }
    else {
        return true;
    }
});
        

Step-7: Apply validation on model.

Open your model and add validation. Please follow below code

namespace MVCCustomValidation
{
    using System;
    using System.Collections.Generic;
    using System.ComponentModel.DataAnnotations;
    
    public partial class Registration
    {
        public int ID { get; set; }
        [Required(ErrorMessage= "Full Name Required!", AllowEmptyStrings=false)]
        public string FullName { get; set; }
        [Required(ErrorMessage = "Username Required!", AllowEmptyStrings = false)]
        public string Username { get; set; }
        [Required(ErrorMessage = "Password Required!", AllowEmptyStrings = false)]
        [DataType(DataType.Password)]
        public string Password { get; set; }
        [Required(ErrorMessage = "Date of Birth Required!", AllowEmptyStrings = false)]
        [DataType(DataType.DateTime)]
        public System.DateTime DOB { get; set; }
        [AtLeastOneRequired("EmailID,MobileNo,LandNo", ErrorMessage = "At Lease one required of EmailID / MobileNo / LandNo")]
        public string EmailID { get; set; }
        public string MobileNo { get; set; }
        public string LandNo { get; set; }
    }
}
        

Step-8: Add a new Controller .

Go to Solution Explorer > Right Click on Controllers folder form Solution Explorer > Add > Controller > Enter Controller name > Select Templete "empty MVC Controller"> Add.

Step-9: Add new action into your controller for Get Method

Here I have added "form" Action into "Registration" Controller. Please write this following code

            public class RegistrationController : Controller
            {
                public ActionResult form()
                {
                    return View();
                }
            }
        

Step-10: Add view for this Action & design.

Right Click on Action Method (here right click on form action) > Add View... > Enter View Name > Select View Engine (Razor) > Check "Create a strong-typed view" > Select your model class > Add.
HTML Code
            @model MVCCustomValidation.Registration

@{
    ViewBag.Title = "form";
}

<h2>form</h2>

@using (Html.BeginForm()) {
    @Html.ValidationSummary(true)
    if (ViewBag.Message != null)
    {
        <div style="width:300px; color:red; padding:5px; border:1px solid green">
            @ViewBag.Message
        </div>
    }
    <fieldset>
        <legend>Registration</legend>

        <div class="editor-label">
            @Html.LabelFor(model => model.FullName)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.FullName)
            @Html.ValidationMessageFor(model => model.FullName)
        </div>

        <div class="editor-label">
            @Html.LabelFor(model => model.Username)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.Username)
            @Html.ValidationMessageFor(model => model.Username)
        </div>

        <div class="editor-label">
            @Html.LabelFor(model => model.Password)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.Password)
            @Html.ValidationMessageFor(model => model.Password)
        </div>

        <div class="editor-label">
            @Html.LabelFor(model => model.DOB)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.DOB)
            @Html.ValidationMessageFor(model => model.DOB)
        </div>

        <div class="editor-label">
            @Html.LabelFor(model => model.EmailID)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.EmailID)
            @Html.ValidationMessageFor(model => model.EmailID)
        </div>

        <div class="editor-label">
            @Html.LabelFor(model => model.MobileNo)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.MobileNo)
            @Html.ValidationMessageFor(model => model.MobileNo)
        </div>

        <div class="editor-label">
            @Html.LabelFor(model => model.LandNo)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.LandNo)
            @Html.ValidationMessageFor(model => model.LandNo)
        </div>

        <p>
            <input type="submit" value="Create" />
        </p>
    </fieldset>
}

<div>
    @Html.ActionLink("Back to List", "Index")
</div>

@section Scripts {
    @Scripts.Render("~/bundles/jqueryval")

    @* I will add our custom js here  *@
    <script src="~/Scripts/MyCustomValidation.js"></script>
}

        

Step-11: Add new action into your controller for POST Method (for form)

Here I have added "form" Action with Model Parameter (here "Registration") into "Registration" Controller. Please write this following code

            [HttpPost]
        public ActionResult form(Registration r)
        {
            if (ModelState.IsValid)
            {
                // here MyDatabaseEntities is our datacontext
                using (MyDatabaseEntities dc = new MyDatabaseEntities())
                {
                    dc.Registrations.Add(r);
                    dc.SaveChanges();
                    ModelState.Clear();
                    r = null;
                    ViewBag.Message = "Success!";
                }
            }
            else
            {
                ViewBag.Message = "Failed!";
            }
            return View(r);
        }
        

Step-12: Run Application.

Download Live Demo

Hello ! My name is Sourav Mondal. I am a software developer working in Microsoft .NET technologies since 2010.

I like to share my working experience, research and knowledge through my site.

I love developing applications in Microsoft Technologies including Asp.Net webforms, mvc, winforms, c#.net, sql server, entity framework, Ajax, Jquery, web api, web service and more.