Model validation in ASP.NET MVC 2.0

Input validation is an important topic in software applications. We should always validate the inputs which are coming through for example input form elements. When we are working with Web Form then we can use the various validator controls for validations. Validation controls can do most of the hard working for a developer. In this post our main discussion is input validation in ASP.NET MVC 2.0

Server side validation

Input validation can be done in two places. One is at the server side and another is at the client side. Server side validation is the actual validation and we should always do that. We should not only depend on the client validation, because client validation is done at browser using some client side scripting like JavaScript. One can easily turn off JavaScript in browser and can able to push invalid data to our application. Server side validation is the safe guard of this kind of problems. If our validation logic has some business rule then we should do that only in server side, because any one can easily see the client side JavaScript code.

Client side validation

On the other hand client side validation is for performance. Because to execute server side validation every time the form needs to be submitted. If we do client side validation then before submitting the form to server our input data can be validated. The user can get a better experience with our application.

Both side

So the summary is we should do input validation at both side. Client side is for performance and server side is for the actual validation and the safe guard. If the input data can or can not be validated at client side then server side always validate it. If some one intentionally disable JavaScript or using some old browser also can not push invalid data to our application because of the server side validation.

Validation with ASP.NET MVC

ASP.NET MVC is for better and maintainable patterns for projects. Here we should not put any logic in views. So how we can do input validation in ASP.NET MVC? The answer is we should do input validation at models. Models can be use in various views and controller in MVC. If we do our validation at model level then it will be DRY (don’t repeat yourself) enough to maintain. Also you can use a view specific model for this job.

ASP.NET MVC also provide some functionality using them we can declaratively implement our validation logic which are so common like required field, compare field, regular expression etc. We can also do our custom validation logic by extending the framework’s existing logic.

Here a short example of the model class with various input validation logic in place with declarative approach.

Model

using System.ComponentModel.DataAnnotations;
using System.Web.Mvc;

namespace ModelValidation.Models
{
    public class Registration
    {
        [Required(ErrorMessage = "Please enter name.")]
        [StringLength(20, ErrorMessage = "Name must be 20 char max.")]
        public string Name { get; set; }

        [Required(ErrorMessage = "Please enter phone number.")]
        [StringLength(10, ErrorMessage = "Phone number must be 10 digit max.")]
        [Display(Name = "Phone Number")]
        public long PhoneNumber { get; set; }

        [Required(ErrorMessage = "Please enter email.")]
        [StringLength(20, ErrorMessage = "Email must be 20 char max.")]
        [DataType(DataType.EmailAddress)]
        [RegularExpression(@"^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$", ErrorMessage = "Please enter valid email id.")]
        public string Email { get; set; }

        [Required(ErrorMessage = "Please enter user name.")]
        [StringLength(20, ErrorMessage = "User name must be 20 char max.")]
        [Display(Name = "User Name")]
        public string UserName { get; set; }

        [Required(ErrorMessage = "Please enter password.")]
        [StringLength(20, MinimumLength = 6, ErrorMessage = "Password name must be in between 6 to 20 char.")]
        [DataType(DataType.Password)]
        public string Password { get; set; }

        [Compare("Password", ErrorMessage = "Password and confirm pssword must match")]
        [Display(Name = "Confirm Password")]
        [DataType(DataType.Password)]
        public string ConfirmPassword { get; set; }

        public Address AddressDetails { get; set; }
    }

    public class Address
    {
        [Required(ErrorMessage = "Please enter Street name.")]
        [StringLength(20, ErrorMessage = "Streen name must be 20 char max.")]
        [Display(Name = "Street Name")]
        public string StreetName { get; set; }

        [Required(ErrorMessage = "Please enter state.")]
        [StringLength(20, ErrorMessage = "State must be 20 char max.")]
        public string State { get; set; }

        [Required(ErrorMessage = "Please enter country.")]
        [StringLength(20, ErrorMessage = "Country must be 20 char max.")]
        public string Country { get; set; }
    }
}

Repository

public interface IRegistrationRepositary
{
    void Register(Registration reg);
}

public class RegistrationRepositary : IRegistrationRepositary
{
    public void Register(Registration reg)
    {
        // Save new Registration to DB here...
    }
}

Controller

using System.Web.Mvc;
using ModelValidation.Models;

namespace ModelValidation.Controllers
{
    public class RegistrationController : Controller
    {
        public IRegistrationRepositary RegisterRepo { get; set; }

        protected override void Initialize(System.Web.Routing.RequestContext requestContext)
        {
            if (RegisterRepo == null)
            {
                RegisterRepo = new RegistrationRepositary();
            }
            base.Initialize(requestContext);
        } 

        //
        // GET: /Registration/Create

        public ActionResult Create()
        {
            return View();
        } 

        //
        // POST: /Registration/Create

        [HttpPost]
        public ActionResult Create(Registration reg)
        {
            try
            {
                // Cleck model state valid or not.
                if (ModelState.IsValid) 
                {
                    // Call the repositary to save the data.
                    RegisterRepo.Register(reg); 
                }
                else
                {
                    return View();
                }

                return RedirectToAction("Index");
            }
            catch
            {
                return View();
            }
        }
    }
}

So we can see here that validating the model state is easy at our controller level.

// Cleck model state valid or not.
if (ModelState.IsValid) 
{
    RegisterRepo.Register(reg);
}

This will enable our server side input validation. For client side validation we simply needs to activate it at view level. The same logic will be implemented at client side using JavaScript.

<script src="../../Scripts/MicrosoftAjax.js" type="text/javascript"></script>
<script src="../../Scripts/MicrosoftMvcValidation.js" type="text/javascript"></script>

<% Html.EnableClientValidation(); %> 

If you are using any object relational model which generated model class with designer tool like Entity Framework database first or model first approach then you can do the following procedure for model validation.

Suppose we have a model class ‘Employee’ which is generated by Entity Framework designer tool.

using System.ComponentModel.DataAnnotations;

namespace ModelValidation.Models
{
    [MetadataType(typeof(EmployeeValidation))]
    public partial class Employee
    {
    }

    public class EmployeeValidation
    {
        public int Id { get; set; }

        [Required(ErrorMessage = "Please enter name.")]
        [StringLength(10)]
        public string Name { get; set; }

        [Required(ErrorMessage = "Please enter department.")]
        [StringLength(10)]
        public string Department { get; set; }
    }
}

Now it will be validated with same approach.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s