Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

A Beginner's Tutorial on Validating Model Data and Unobtrusive Client side Validation in ASP.NET MVC

0.00/5 (No votes)
15 Apr 2013 1  
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.

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 check ModelState.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.

History

  • 15 April 2013: First version.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here