You are on page 1of 10

A Beginner's Tutorial on Validating Model Data

and Unobtrusive Client side Validation in


ASP.NET MVC
Rahul Rajat Singh, 15 Apr 2013

Introduction
In this article we will try to see how we can use DataAnnotations to perform validations of Model
classes in an ASP.NET MVC application. We will see how using simple script includes will provide us
with the unobtrusive client side validations using the same DataAnnotations attribute's logic.

Background
Whenever we are creating database driven applications. validations of user input is a very important
aspect. We need to validate all the data that is coming as user input to ensure that the data entered
is valid and conforms to the data type and length values of the respective field in the database.

In a MVC application, The business entities are represented as Model classes. Now if we need to
validate the values of these model classes before pushing the data into the database we have two
options. First option is that we write all the client side scripts to validate the individual fields and also
the server side code for validations before putting the data into the Model. Now this server side is
little problematic if we have strongly typed views are strongly typed. It is not a good idea
to validate all the fields' data individually.

The second option is more elegant and is very much supported by the MVC framework. This option
is to decorate the individual propertied with the DataAnnotation attributes. Now using these
attributes we can specify various validation rules on individual fields of a Model class. This way we
don't have to write any extra validation code ourselves. Specifying
these DataAnnotation attributes will take care of both server side and client side validations itself.

The DataAnnotation attributes rely on the fact that whenever we try to add new record or update
an existing record, we will always checkModelState.IsValid property. This will use
the specified values in the attributes of the Model and check for validation non conformance. In case
the data is not valid, no action will be taken and the the user will be presented with the problems in
the data.

Let us now see how we can put simple DataAnnotation attributes with a Model class and it will
Take care of the client side and server side validations.
Using the code
Database and Validation Rules

Let is create a single table database. We will create a single table called as Contacts which will
contain the information of a contact person.

Now in this table, All the fields but ID are not-null i.e. they will be required from the user. Also, we
have following length constraints on the individual fields.

 FirstName: varchar(50)
 LastName: varchar(50)
 Address: varchar(100)
 PhoneNumber: varchar(15)
 eMail: varchar(35)

So another validation rule for this table should be that the data coming from the user should not
exceed the maximum length of the individual fields. Another validation rule is that the phone
number should only be numeric and should not contain the alphabets. And the email ID should be in
the proper format.

So let us try to summarize the validation rules required for this table.

1. All the fields are required.


2. The length of user input should not exceed the length of respective fields.
3. PhoneNumber should contain only numbers.
4. eMail should be in the proper email format.

Now lets take these rules as the validation requirements for our application and start working on
them.

Data Access
Now to perform data access we could use anything ranging from classic ADO.NET to ORMs like
entity framework provided that we model our data in terms of Model classes. Let us use entity
framework so that all the boilerplate code for data access and data entities will be generated for us.

Once we have ADO.NET Entity Data Model added for this database we will have the following entity
created to be used as Model class in our application.

Creating the MVC application

Let us now add a simple controller that will provide the CRUD operations on this table/entity. Lets
use the scaffolds to generate the controller and views so that we can put our focus on data
validations only rather than creating controllers and view.
The Controller code will now look like:

public class ContactController : Controller


{
private SampleDbEntities db = new SampleDbEntities();

public ViewResult Index()


{
return View(db.Contacts.ToList());
}

public ViewResult Details(int id)


{
Contact contact = db.Contacts.Single(c => c.ID == id);
return View(contact);
}

public ActionResult Create()


{
return View();
}

[HttpPost]
public ActionResult Create(Contact contact)
{
if (ModelState.IsValid)
{
db.Contacts.AddObject(contact);
db.SaveChanges();
return RedirectToAction("Index");
}

return View(contact);
}

public ActionResult Edit(int id)


{
Contact contact = db.Contacts.Single(c => c.ID == id);
return View(contact);
}

[HttpPost]
public ActionResult Edit(Contact contact)
{
if (ModelState.IsValid)
{
db.Contacts.Attach(contact);
db.ObjectStateManager.ChangeObjectState(contact, EntityState.Modified);
db.SaveChanges();
return RedirectToAction("Index");
}
return View(contact);
}

public ActionResult Delete(int id)


{
Contact contact = db.Contacts.Single(c => c.ID == id);
return View(contact);
}
[HttpPost, ActionName("Delete")]
public ActionResult DeleteConfirmed(int id)
{
Contact contact = db.Contacts.Single(c => c.ID == id);
db.Contacts.DeleteObject(contact);
db.SaveChanges();
return RedirectToAction("Index");
}

protected override void Dispose(bool disposing)


{
db.Dispose();
base.Dispose(disposing);
}
}

and the view created to perform the CRUD operations looks like

The Default Behavior

Now when we run the application we have the basic CRUD operations working for us. Now if we try
to create a new entry and put some invalid data the data will be submitted there are no validations in
place. Well not entirely true, entity framework is intelligent enough to detect the required fields and
validate against them. So if we try to submit without any values we will get some error message. But
these will be default messages generated by entity framework.

Now for the length, If we try to put the data that is of more length than an exception will be thrown.
Now we can simple avert this exception if we could validate the incoming data and check for the
length.

And finally, for phone number and email format, there is no way they are getting validated. As long
as they are of valid length, they will simply be pushed into the database.

DataAnnotations
Now let us not depend on the default behavior and take control of the validation behavior in our
hand. We will do this by adding DataAnnotation attributes in our Model class. Since our model
class is auto generated will create a partial class with same name to add the data annotations on it.
[MetadataType(typeof(ContactMetaData))]
public partial class Contact
{
}

Now this class is adorned with the MetadataType attribute which is present
in DataAnnotations namespace. This indicated that the meta data for this Model class will be
present in ContactMetaData class. So this

ContactMetaData

class will be the place to put in all our validation logic. Now this meta data class should contain same
public properties as that of the Model class it is associated with.

Let us now take all the requirements one by one and try to put respective attributes with respective
properties of the Model class.

All field are required

Now this can be achieved by putting the Required attribute with the properties as:

class ContactMetaData
{
[Required(ErrorMessage="First Name is required")]
public string FirstName { get; set; }

[Required(ErrorMessage = "Last Name is required")]


public string LastName { get; set; }

[Required(ErrorMessage = "Address is required")]


public string Address { get; set; }

[Required(ErrorMessage = "Phone Number is required")]


public string PhoneNumber { get; set; }

[Required(ErrorMessage = "eMail is required")]


public string eMail { get; set; }
}

The length of user input should not exceed the length of respective fields

Now this can be done by specifying the StringLength attribute with all the properties.

class ContactMetaData
{
[Required(ErrorMessage="First Name is required")]
[StringLength(15, ErrorMessage = "First Name length Should be less than 50")]
public string FirstName { get; set; }

[Required(ErrorMessage = "Last Name is required")]


[StringLength(50, ErrorMessage = "Last Name length Should be less than 50")]
public string LastName { get; set; }

[Required(ErrorMessage = "Address is required")]


[StringLength(100, ErrorMessage = "Address length Should be less than 100")]
public string Address { get; set; }

[Required(ErrorMessage = "Phone Number is required")]


[StringLength(15, ErrorMessage = "Phone Number length Should be less than 15")]
public string PhoneNumber { get; set; }

[Required(ErrorMessage = "eMail is required")]


[StringLength(35, ErrorMessage = "eMail Length Should be less than 35")]
public string eMail { get; set; }
}

PhoneNumber and email Format

Now the next validation is for the phone number and email format. To do this let us try to use
regular expressions. All the input will be validated against a regular expression which is specified
as RegularExpression attribute for the respective properties.

[RegularExpression(@"^[0-9]{0,15}$", ErrorMessage = "PhoneNumber should contain only


numbers")]
public string PhoneNumber { get; set; }

[RegularExpression(@"^\w+@[a-zA-Z_]+?\.[a-zA-Z]{2,3}$", ErrorMessage = "eMail is not in proper


format")]
public string eMail { get; set; }

Note: We have not seen the use of Range attribute. It is used to specify range and its use is fairly
straight forward.

Client Side Unobtrusive Validations

Now these attributes will take care of server side validations. To use the same from client side we
need to include a couple of client side scripts and the same validation rules will work from client side
too(providing immediate feedback to the user).

<script src="@Url.Content("~/Scripts/jquery.validate.min.js")"
type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")"
type="text/javascript"></script>

Testing the application

Now we have the validation rules for our entity in place. Let us now try to see this in action. Lets try
to submit the form without putting any values.
Now lets try to put long data in some field and the number and email ID in wrong format.
But if all the data is valid the create operation will be successful with all the validations passed.
And thus by putting DataAnnotation attributes in the Model's metadata classes we have created
both client side and server side validation for our Model classes.

Point of interest
In this article we saw how we can use DataAnnotation namespace to decorate the Model's meta
data classes and perform server side and client side unobtrusive validations. This article has been
written from a beginner's perspective. I hope this has been informative.

You might also like