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
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.
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.
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.
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
This article has been editorially reviewed by Suprotim Agarwal.
C# and .NET have been around for a very long time, but their constant growth means there’s always more to learn.
We at DotNetCurry are very excited to announce The Absolutely Awesome Book on C# and .NET. This is a 500 pages concise technical eBook available in PDF, ePub (iPad), and Mobi (Kindle).
Organized around concepts, this Book aims to provide a concise, yet solid foundation in C# and .NET, covering C# 6.0, C# 7.0 and .NET Core, with chapters on the latest .NET Core 3.0, .NET Standard and C# 8.0 (final release) too. Use these concepts to deepen your existing knowledge of C# and .NET, to have a solid grasp of the latest in C# and .NET OR to crack your next .NET Interview.
Click here to Explore the Table of Contents or Download Sample Chapters!
Was this article worth reading? Share it with fellow developers too. Thanks!
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