Server Side Validation With ASP.NET MVC And Data Annotations

Posted by: Malcolm Sheridan , on 11/10/2009, in Category ASP.NET MVC
Views: 26246
Abstract: The following article demonstrates how to perform server side validation using ASP.NET MVC and data annotations.
Server Side Validation With ASP.NET MVC And Data Annotations
 
When you’re using ASP.NET MVC, there’s no validation controls for you compared to ASP.NET WebForms. It is always important to validate data on the server as well as the client. Back when Dynamic Data was being developed, a set of attributes was created to help tell the Dynamic Data folks about validation and other metadata so they could create smart scaffolds. What this allows you to do is decorate your classes or properties with validation attributes. A project that is available on CodePlex gives you the power to inject this validation into your MVC project. The CodePlex project can be found here. The end results are you can decorate your classes with some of the following attributes to perform server side validation:
  • Required – a required field
  • StringLength – allows you to set the minimum and maximum length of a string
  • RegularExpression – performs regular expression validation
 

 

When you use this your validation classes will look like the following example:
 
C#
 
public class EmployeeMetaData
{
[Required]
      [StringLength(10, ErrorMessage="Given name cannot be more than 10 characters")]
      public string GivenName { get; set; }
 
      [Required]
      public string Surname { get; set; }
}
 
VB.NET
 
Public Class EmployeeMetaData
Private privateGivenName As String
<Required, StringLength(10, ErrorMessage:="Given name cannot be more than 10 characters")> _
Public Property GivenName() As String
      Get
            Return privateGivenName
      End Get
      Set(ByVal value As String)
            privateGivenName = value
      End Set
End Property
 
       Private privateSurname As String
       <Required> _
       Public Property Surname() As String
             Get
                   Return privateSurname
             End Get
             Set(ByVal value As String)
                   privateSurname = value
             End Set
       End Property
End Class
 
Before going any further you’ll need to install ASP.NET MVC. You can download that here. To begin with open Visual Studio 2008 and choose File > New > Project > ASP.NET MVC Web Application. I’m going to keep the model simple, so add the following Employee class to the Models folder:
C#
public partial class Employee
{
public int ID { get; set; }
      public string GivenName { get; set; }
      public string Surname { get; set; }
 
      public List<Employee> FetchEmployees()
      {
            var employees = new List<Employee>();
            employees.Add(new Employee() { ID = 1, GivenName = "Malcolm", Surname = "Sheridan" });
            employees.Add(new Employee() { ID = 2, GivenName = "Suprotim", Surname = "Agarwal" });
           return employees;
      }
 
      public Employee FetchEmployee(int id)
      {
            var employees = FetchEmployees();
            return (from p in employees
                           where p.ID == id
                           select p).First();   
      }
}
VB.NET
Partial Public Class Employee
Private privateID As Integer
Public Property ID() As Integer
      Get
            Return privateID
      End Get
      Set(ByVal value As Integer)
            privateID = value
      End Set
End Property
       Private privateGivenName As String
       Public Property GivenName() As String
             Get
                   Return privateGivenName
             End Get
             Set(ByVal value As String)
                   privateGivenName = value
             End Set
       End Property
       Private privateSurname As String
       Public Property Surname() As String
             Get
                   Return privateSurname
             End Get
             Set(ByVal value As String)
                   privateSurname = value
             End Set
       End Property
 
       Public Function FetchEmployees() As List(Of Employee)
             Dim employees = New List(Of Employee)()
                  employees.Add(New Employee() With {.ID = 1, .GivenName = "Malcolm", .Surname = "Sheridan"})
                  employees.Add(New Employee() With {.ID = 2, .GivenName = "Suprotim", .Surname = "Agarwal"})
                  Return employees
       End Function
 
       Public Function FetchEmployee(ByVal id As Integer) As Employee
                  Dim employees = FetchEmployees()
                  Return ( _
                      From p In employees _
                      Where p.ID = id _
                      Select p).First()
       End Function
End Class
The class above will return a list of employees and a single employee that I’ll use in this example. To get the validation to work properly, you need to add references to the following assemblies. Both can be found in the CodePlex project’s bin folder:
System.ComponentModel.DataAnnotations.dll
Microsoft.Web.Mvc.DataAnnotations.dll
 
AddReference
 
Once that’s done the last thing to do is register the default binder for the project. Open up the Global.asax file and add the following code:
 
C#
 
protected void Application_Start()
{
RegisterRoutes(RouteTable.Routes);
      ModelBinders.Binders.DefaultBinder = new Microsoft.Web.Mvc.DataAnnotations.DataAnnotationsModelBinder();
}
 
VB.NET
 
Protected Sub Application_Start()
RegisterRoutes(RouteTable.Routes)
       ModelBinders.Binders.DefaultBinder = New Microsoft.Web.Mvc.DataAnnotations.DataAnnotationsModelBinder()
End Sub
 
That’s it! Now we just need to write the validation for our employees now. The Employee class must be a partial class so we can add validation attributes to the respective properties.   Create a new class file called EmployeeMetaData and add the following code:
 
C#
 
[MetadataType(typeof(EmployeeMetaData))]
public partial class Employee
{}
 
 public class EmployeeMetaData
 {
      [Required]
      [StringLength(10, ErrorMessage="Given name cannot be more than 10 characters")]
      public string GivenName { get; set; }
 
      [Required]
      public string Surname { get; set; }
}
 
VB.NET
 
<MetadataType(GetType(EmployeeMetaData))> _
Partial Public Class Employee
End Class
 
 Public Class EmployeeMetaData
       Private privateGivenName As String
       <Required, StringLength(10, ErrorMessage:="Given name cannot be more than 10 characters")> _
       Public Property GivenName() As String
             Get
                   Return privateGivenName
             End Get
             Set(ByVal value As String)
                   privateGivenName = value
             End Set
       End Property
 
       Private privateSurname As String
       <Required> _
       Public Property Surname() As String
             Get
                   Return privateSurname
             End Get
             Set(ByVal value As String)
                   privateSurname = value
             End Set
       End Property
 End Class
 
The first class is a partial Employee class. What this is doing is instructing the Employee class to use the EmployeeMetaData class as the validation class. I’ve added the [Required] attribute to both the GivenName and Surname properties. This means they’re both required. The GivenName will also check the length of the value by adding the [StringLength] attribute. Cool huh?!  To see this in action add an Employee controller to the Controllers folder and add the following code:
 
C#
 
public class EmployeeController : Controller
    {       
        public ActionResult Index()
        {
            var employee = new Employee();
            return View(employee.FetchEmployees());
        }
 
        public ActionResult Edit(int id)
        {
            var employee = new Employee();
            return View(employee.FetchEmployee(id));
        }               
 
        [AcceptVerbs(HttpVerbs.Post)]
        public ActionResult Edit(int id, Employee employee)
        {
            try
            {               
                if (!ModelState.IsValid)
                    return View(employee);
                else
                    // update data here...
                    return RedirectToAction("Index");
            }
            catch
            {
                return View();
            }
        }
    }
 
VB.NET
 
Public Class EmployeeController
      Inherits Controller
            Public Function Index() As ActionResult
                  Dim employee = New Employee()
                  Return View(employee.FetchEmployees())
            End Function
 
            Public Function Edit(ByVal id As Integer) As ActionResult
                  Dim employee = New Employee()
                  Return View(employee.FetchEmployee(id))
            End Function
 
            <AcceptVerbs(HttpVerbs.Post)> _
            Public Function Edit(ByVal id As Integer, ByVal employee As Employee) As ActionResult
                  Try
                        If (Not ModelState.IsValid) Then
                              Return View(employee)
                        Else
                              ' update data here...
                              Return RedirectToAction("Index")
                        End If
                  Catch
                        Return View()
                  End Try
            End Function
End Class
 
In the code above, the Index action is executing the FetchEmployees method to return the list of employees. This will be used for the Index view. 
 
MVC_Application_Index
 
You edit an employee by clicking on the Edit link. This will invoke the Edit action. This action calls the FetchEmployee method which returns a single employee.
 
MVC_Application_Edit
 
When the user tries to save the data, the validation will occur on the server automatically. The validation result can be checked by calling the ModelState.IsValid property. If validation fails, the action will return the current view with the employee. In the view, a summary of validation errors will be displayed.
 
MVC_Application_EditErrors
 
This is a nice way to perform server side validation when you’re using MVC. The entire source code of this article can be downloaded over here
Give a +1 to this article if you think it was well written. Thanks!
Recommended Articles
Malcolm Sheridan is a Microsoft awarded MVP in ASP.NET, a Telerik Insider and a regular presenter at conferences and user groups throughout Australia and New Zealand. Being an ASP.NET guy, his focus is on web technologies and has been for the past 10 years. He loves working with ASP.NET MVC these days and also loves getting his hands dirty with jQuery and JavaScript. He also writes technical articles on ASP.NET for SitePoint and other various websites. Follow him on twitter @malcolmsheridan


Page copy protected against web site content infringement by Copyscape


User Feedback
Comment posted by bukmacher on Friday, November 13, 2009 5:42 PM
ok ,help a lot <a href="http://bukmacher1x2.com.pl">bukmacher</A>
Comment posted by Knoeller on Sunday, December 27, 2009 12:50 AM
Thanks for explaining this concept so clearly
Comment posted by Vinod on Wednesday, March 13, 2013 2:16 AM
Hi everyone, i have a dropdownlist called ddl in the item templete of a Datalist name dlOrder.  dlOrder displays a product and the price along with the ddl(dropdownlist control) which holds the quanity 1 to 10. i want when a customer selects the quantity it should automatically add to cart without clicking on a buttom. I implemented the selectedIndexChange event but it doesn't work. can some one help me with this. am a novies in Asp.net

Post your comment
Name:  
E-mail: (Will not be displayed)
Comment:
Insert Cancel