Monday, January 9, 2012

Custom Validation using DataAnnotationsModelValidator


Hi,

After long time I like to write some more tips on validation in MVC  3.0  because it’s very cool as using this much code not required to write in JavaScript and jquery so avoid put business logic needs to write in client side. Here I explain custom validation using loan module

Here is my Validation class 
// Comment
    public class SalaryAttributes : ValidationAttribute
    {
        private readonly int _minSalary = 0;

        public SalaryAttributes(int minSalary)
        {
            _minSalary = minSalary;
        }

        protected override System.ComponentModel.DataAnnotations.ValidationResult IsValid(object value, System.ComponentModel.DataAnnotations.ValidationContext validationContext)
        {
            if (value != null)
            {
                int data = (int)value;
                if (data < _minSalary)
                {
                    return new ValidationResult("Salary must be more than "+ _minSalary.ToString());
                }                
            }
            return ValidationResult.Success;
        }
    }
This class will check salary of person required more than pass min salary if not it will display message
Now we needs to add this validation attributes in dataanotationvalidation model
We can add using wrap other class and override GetClientValidationRules
Which contain basic rules

// Comment

public class SalaryValidator : DataAnnotationsModelValidator
    {
        int minSalary = 0;
        string errorMsg = string.Empty;

        public SalaryValidator(ModelMetadata metadata, ControllerContext context, SalaryAttributes attributes)
            : base(metadata, context, attributes)
        {
            errorMsg = attributes.ErrorMessage;
        }

        public override IEnumerable GetClientValidationRules()
        {
            ModelClientValidationRule ValidationRule = new ModelClientValidationRule();
            ValidationRule.ErrorMessage = errorMsg;
            ValidationRule.ValidationType = "Salary";
            ValidationRule.ValidationParameters.Add("minSalary", minSalary);
            return new[] { ValidationRule };
        }
    }

Now quick looks my model contain 2 class Customer and dataaccess of customer
Where I have pass min salary is 20,000 which is min salary so not allow less than this

// Comment


    public class Customer
    {
        [Required]
        public string Customers { get; set; }
        [Required]
        public string city { get; set; }
        [SalaryAttributes(20000)]
        public int Salary { get; set; }

    }


    public class DataAccess
    {
        static List lstCustomer=new List();
        public DataAccess()
        {
            lstCustomer.Clear();
            lstCustomer.Add(new Customer(){ Customers="bhavik", city="Ahmedabad", Salary=28000 });
            lstCustomer.Add(new Customer(){ Customers="sandeep", city="Ahmedabad", Salary=21000 });
            lstCustomer.Add(new Customer(){ Customers="Shumit", city="Ahmedabad", Salary=25000 });
        }

        public List getCustomer()
        {
            return lstCustomer;
        }

        public void addCustomer(Customer cust)
        {
            lstCustomer.Add(cust);
        }

    }

Now quick create customer Controllers which contain index and xreate method
Now using index and create method generate view with model customer

// Comment


  [HandleError]
    public class CustomerController : Controller
    {
        DataAccess objContex = new DataAccess();
        //
        // GET: /Customer/

        public ActionResult Index()
        {
            var Customers = objContex.getCustomer();
            return View(Customers);
        }

        public ActionResult Create()
        {
            var Customer = new Customer();
            return View(Customer);
        }

        [HttpPost]
        public ActionResult Create(Customer obj)
        {
            try
            {
                var Customer = new Customer();
                if (ModelState.IsValid)
                {
                    Customer.city = obj.city;
                    Customer.Customers = obj.Customers;
                    Customer.Salary = obj.Salary;
                    objContex.addCustomer(Customer);        
                    return View("Index");
                }
                else
                {
                    return View(obj);
                }
            }


            catch (Exception)
            {
                var Customer = new Customer();
                return View(Customer);
            }
        }

    }

Look at generated code for index and customer
// Comment

@model IEnumerable

@{
    ViewBag.Title = "Index";
}

Index

@Html.ActionLink("Create New", "Create") @foreach (var item in Model) { }

Customers

city

Salary

@Html.DisplayFor(modelItem => item.Customers)

@Html.DisplayFor(modelItem => item.city)

@Html.DisplayFor(modelItem => item.Salary)

@Html.ActionLink("Edit", "Edit", new { /* id=item.PrimaryKey */ }) |
@Html.ActionLink("Details", "Details", new { /* id=item.PrimaryKey */ }) |
@Html.ActionLink("Delete", "Delete", new { /* id=item.PrimaryKey */ })
@model ASPNET_MVC3_Custom_ModelValidation.Models.Customer @{ ViewBag.Title = "Create"; }

Create

@using (Html.BeginForm()) { @Html.ValidationSummary(true)
Customer
@Html.LabelFor(model => model.Customers)
@Html.EditorFor(model => model.Customers) @Html.ValidationMessageFor(model => model.Customers)
@Html.LabelFor(model => model.city)
@Html.EditorFor(model => model.city) @Html.ValidationMessageFor(model => model.city)
@Html.LabelFor(model => model.Salary)
@Html.EditorFor(model => model.Salary) @Html.ValidationMessageFor(model => model.Salary)
}
@Html.ActionLink("Back to List", "Index")

Now run code and check how validation work

Customer Validation using DataAnnotationsModelValidator