Hi Folks
Today we are
going to learn how to implement Client side validation and Server side
validation using Custom Data annotation attributes in Asp.Net MVC.
Well,
First i would like to list out some
pre-defined Data Annotations which are being used in Asp.Net MVC.
- [Required]
- [Compare]
- [DataType]
- [DisplayFormat]
and many more
Some
times developers want to validate the data which is no more possible with
predefined data annotations as per the requirement. For Ex : In Job application
form, developer wants to validate person age to restrict the candidate from
filling the form and enable them to apply only for particular age .So here
we don't get any data annotation attribute to check age constraint.So here we
are going to implement custom data annotations to validate data as per our
requirement.
Step 1:
Create a New Asp.Net MVC Web
Application and select Basic Template.
Step 2:
Create a model class.
Go to Models folder and
right click , Add -->Class.Give name as 'UserProfile'.
Now,I will add some
properties for the class.
In above picture you can
observe i have added some custom attributes( [CheckAge] and [ExcludeChar])
along with predefined attributes to validate the data.
Step 3:
- Well,now i will create one folder from root directory
of the application as 'CustomAttributes'
- Inside this folder i will create one class and
ll be writing code to create and implement custom validation
attributes.
- Have a look at
code which implements custom validation attributes..
using System;
using System.Collections.Generic;
using
System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Web;
using System.Web.Mvc;
namespace CustomValidation.CustomAttributes
{
public class ExcludeChar : ValidationAttribute, IClientValidatable
{
private string _chars;
private string errorMessage;
public ExcludeChar(string chars)
: base("{0} contains invalid
character.")
{
_chars = chars;
}
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
if
(value != null)
{
for
(int i = 0; i < _chars.Length; i++)
{
var valueAsString = value.ToString();
if
(valueAsString.Contains(_chars[i]))
{
errorMessage = FormatErrorMessage(validationContext.DisplayName);
return new ValidationResult(errorMessage);
}
}
}
return ValidationResult.Success;
}
public IEnumerable<ModelClientValidationRule>
GetClientValidationRules
(ModelMetadata metadata, ControllerContext
context)
{
ModelClientValidationRule mcvrTwo = new ModelClientValidationRule();
mcvrTwo.ValidationType
= "excludechar";
mcvrTwo.ErrorMessage =
"User Name contains
invalid character";
mcvrTwo.ValidationParameters.Add("otherpropertyname",
_chars);
yield return mcvrTwo;
}
}
public class CheckAge : ValidationAttribute
{
private int _UserAge;
public CheckAge(int Age, string errormsg)
: base(errormsg)
{
this._UserAge
= Age;
}
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
ValidationResult validationResult = ValidationResult.Success;
if
(value != null)
{
var
UserAgeVal = Convert.ToInt32(value);
if
(UserAgeVal > _UserAge)
validationResult = new ValidationResult(ErrorMessageString);
}
return validationResult;
}
}
}
Now, we just go through
the code and analyze it. We have created ExcludeChar class and this class
inherihating parent class called ‘ValidationAttribute’ class and ‘IClientValidatable’ interface.
·
ExcludeChar
class using parent’s method IsValid() and overrides it to do some logic to exclude
unwanted character from being entered.
·
It
also implements GetClientValidationRules() method of IClientValidatable interface to enable unobtrusive client
validation.
Note :
For Server side
validation only IsValid() method is enough to fire the validation.But only the
thing is we need to check modelstate.IsValid() in post request method of
controller as shown.
[HttpPost]
public ActionResult UserProfile(UserProfile model)
{
if
(!ModelState.IsValid)
{
return View(model);
}
return View(model);
}
Step 4: Create
Controller
Step 5: Create Views
·
Index View
·
UserProfile View
@{
ViewBag.Title = "Index";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<br />
<br />
<h2>Index</h2>
<hr />
<br />
<textarea class="form-control" rows="3" readonly="readonly" style="height: 50%;
width: 50%">
Hi Guys..This Appplication
Demonstrates How to impliment Client Validation and Server Validation using
Custom Data Annotation Attributes.
</textarea>
@model CustomValidation.Models.UserProfile
@{
ViewBag.Title = "UserProfile";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<br /><br
/>
<h2>UserProfile</h2>
<hr />
<script src="~/Scripts/jquery-1.10.2.js"></script>
<script src="~/Scripts/jquery.validate.min.js"></script>
<script src="~/Scripts/jquery.validate.unobtrusive.min.js"></script>
<script src="~/Scripts/jquery-migrate-1.2.1.js"></script>
<script src="~/Scripts/CustomVal.js"></script>
<script src="~/Scripts/jquery-ui-1.11.2.min.js"></script>
<script>
$(function () {
$("#DOB").datepicker();
});
</script>
@using (Html.BeginForm("UserProfile", "Home", FormMethod.Post))
{
<div>
<div>
<p>
@Html.LabelFor(m
=> m.UserName)
</p>
<div>
@Html.TextBoxFor(m
=> m.UserName, new { @class = "form-control" })
@Html.ValidationMessageFor(m
=> m.UserName)
</div>
<p>
@Html.LabelFor(m
=> m.Age)
</p>
<div>
@Html.TextBoxFor(m
=> m.Age, new { @class = "form-control" })
@Html.ValidationMessageFor(m
=> m.Age)
</div>
<p>
@Html.LabelFor(m
=> m.DOB)
</p>
<div>
@Html.TextBoxFor(m
=> m.DOB, new { @class = "form-control" })
@Html.ValidationMessageFor(m
=> m.DOB)
</div>
<p>
@Html.LabelFor(m
=> m.City)
</p>
<div>
@Html.TextBoxFor(m
=> m.City, new { @class = "form-control" })
@Html.ValidationMessageFor(m
=> m.City)
</div>
<p>
@Html.LabelFor(m
=> m.Address)
</p>
<div>
@Html.TextBoxFor(m
=> m.Address, new { @class = "form-control" })
@Html.ValidationMessageFor(m
=> m.Address)
</div>
<div style="padding-top: 15px">
<input type="submit" value="Save" class="btn btn-success" />
</div>
</div>
</di>
Step 5: Create javascript file and add jquery code to
handle unobtrusive client validation
And code is as follows
$.validator.addMethod("excludechar",
function (value, element, param) {
var characterReg = new
RegExp("^[a-zA-Z]+$");
var result = false;
if (characterReg.test(value)) {
result = true;
}
return result;
});
$.validator.unobtrusive.adapters.add
("excludechar", ["otherpropertyname"],
function (options) {
options.rules["excludechar"] = options.params.otherpropertyname;
options.messages["excludechar"] = options.message;
});
Important Note:
You can observe in GetClientValidationRules()
of CustomAttribute Class,there we have written following line of code.
mcvrTwo.ValidationType = "excludechar";
mcvrTwo.ErrorMessage = "User Name contains invalid character";
mcvrTwo.ValidationParameters.Add("otherpropertyname",
_chars);
Here we have given
validation type as ‘excludechar and
parametername as ‘otherpropertyname’.We
just re-called this piece of code only because that the methods
jquery.validator.add() and $.validator.unobtrusive.adapters.add()
have got some parameters.So name of this parameter should match validationtype
and validationpaarameters of property of class ‘ModelClientValidationRule’.
Step 6 :
Add Layout
File.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,
initial-scale=1.0">
<title>@ViewBag.Title - My ASP.NET Application</title>
@Styles.Render("~/Content/css")
@Scripts.Render("~/bundles/modernizr")
@Scripts.Render("~/bundles/jqueryui")
@Styles.Render("~/Content/themes/base/css")
</head>
<body>
<div class="navbar navbar-inverse
navbar-fixed-top">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
@Html.ActionLink("Application name", "Index", "Home", null, new { @class = "navbar-brand" })
</div>
<div class="navbar-collapse collapse">
<ul class="nav navbar-nav">
<li>@Html.ActionLink("Home", "Index", "Home")</li>
<li>@Html.ActionLink("About", "About", "Home")</li>
<li>@Html.ActionLink("Contact", "UserProfile",
"Home")</li>
</ul>
</div>
</div>
</div>
<div class="container body-content">
@RenderBody()
<hr />
<footer>
<p>© @DateTime.Now.Year - My ASP.NET Application</p>
</footer>
</div>
</body>
</html>
Note :
Add required jquery plugins and here we have used Bootstrap to improve look and
feel of the application.
- Jquery plugins used are :
·
jquery-1.9.1
·
jquery.validate
·
jquery.validate.unobtrusive
Step 7 : Run the
Application and see the output.
1.Home Page
2.User Profile
- As you can see in above pic, when user clicks
Save button it will through server validation.
- Client side validation
thrown when user enters invalid characters n gets out of focus .Here we used custom
validation attribute to avoid invalid characters from being inserted.
- Server side validation
thrown when user enters user age more than 50 n clicks save button.Here we used custom
validation attribute to restrict the user
from
being saved who has age more than 50.
Thank you guys.. I hope this post will be helpful for you.And let me know if you have any concerns and any issues.
Very Informative article sanjeev.
ReplyDeleteThank you sushil..
DeleteVery useful post Sanjeev.
ReplyDeleteThank you Lagnajit
DeleteThis comment has been removed by the author.
Deletenice explanation sanjeev
ReplyDeleteThank you..
Delete