Friday 24 January 2014

MVC Tips : Implement IValidatableObject Interface for custom validation in ASP.Net MVC 4

Click Here to Download ImplementIValidateObjectInterfaceInMVC.zip Example.

We can validate model itself by implementing IValidatableObject Interface. For validation you need to implement 'Validate' method of IValidatableObject Interface.

Here is some difference from the attribute validation version.
  • In this for validation method is 'Validate' instead of 'IsValid' and also return type and parameter is different.
  • The return type for Validate is an IEnumerable<ValidationResult>, because the logic inside this method is validating the entire model and might need to return more than a single validation error.
  • No parameter is passed to Validate because you  can directly access model properties because this Validate method is inside model.

Here is example for this.

In this example we take one employee form which has three fields 'Name', 'Date Of Birth' and 'Joining Date'. We define these properties in 'Employee' model.
Now we implement IValidatableObject Interface and use it's 'Validate' method to validate some custom validation rules.

These rules are :
  • Date of birth should not greater than today.
  • Joining date should not greater than date of birth.
  • Joining date should not greater than today

Now we write if condition for each rule. If condition is violate at that time we throw 'ValidationResult' object with property validation error message. This 'ValidationResult' object has one another parameter called 'MemberNames', which accepts array of field member for which this error is associate.
By supplying 'MemberName' error message is displayed near particular field position.

In 'Validate' method code you can see that we are using 'yield return' to return 'ValidationResult' object. The reason for doing this is, it builds the enumerable return value.

In screen shot you can see that validation message is also place at appropriate locations.

Employee Model (Employee.cs) : 
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Web;

namespace MvcApplication1.Models
{
    public class Employee : IValidatableObject
    {
        [Required]
        public string Name { get; set; }

        [Required]
        [Display(Name = "Date Of Date")]
        public DateTime DOB { get; set; }

        [Required]
        [Display(Name= "Joining Date")]
        public DateTime JoiningDate { get; set; }



        IEnumerable<ValidationResult> IValidatableObject.Validate(ValidationContext validationContext)
        {
                        

            if (DOB > DateTime.Now)
            {
                yield return new ValidationResult("Date of birth can not be greater than today", new[] { "DOB" });
            }

            if (DOB > JoiningDate)
            {
                yield return new ValidationResult("Date of bith can not be greater than joining date.", new[] { "DOB", "JoiningDate" });
            }

            if (JoiningDate > DateTime.Now)
            {
                yield return new ValidationResult("Joining date can not be greater than today", new[] { "JoiningDate" });
            }
        }
    }
}

Controller (CreateController.cs) :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using MvcApplication1.Models;

namespace MvcApplication1.Controllers
{
    public class CreateController : Controller
    {
        //
        // GET: /Create/

        public ActionResult Index()
        {
            return View();
        }
        [HttpPost]
        public ActionResult Index(Employee obj)
        {
            return View();
        }
    }
}

View (Index.cshtml) :
@model MvcApplication1.Models.Employee

@{
    ViewBag.Title = "Index";
}

<h2>Index</h2>

@using (Html.BeginForm()) {
    @Html.ValidationSummary(true)

    <fieldset>
        <legend>Employee</legend>

        <div class="editor-label">
            @Html.LabelFor(model => model.Name)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.Name)
            @Html.ValidationMessageFor(model => model.Name)
        </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.JoiningDate)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.JoiningDate)
            @Html.ValidationMessageFor(model => model.JoiningDate)
        </div>

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

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

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

Screen shot 1 : Error message were dates greater than today

MVC Implement IValidatableObject Interface Date greater than today

Screen shot 2 : Error message were date of birth could not greater than joining date 

MVC Implement IValidatableObject Interface Date of birth could not greater than joining date



Below are the books that you would like :

No comments:

Post a Comment