Sunday, August 21, 2011

ASP.Net MVC - validating if an email address is already in use

Problem

The need to check if an email is already registered by a signed up user is a very common scenario that any application using Forms Authentication need to cater for. Ideally you want to make use of Ajax so that the user can get instant feedback and it should fit into your current client side validation framework. At CBSL we use the JQuery Validation plugin to achieve this, it is very well featured and infintely customisable and makes it easy to cater for this scenario.

Solution
The code in the .cshtml view file looks as follows (please note that I have removed the master page to make the code simpler to replicate):
<html>
<head>
    <title>@ViewBag.Title</title>
    <script src="@Url.Content("~/Scripts/jquery-1.5.1.min.js")" type="text/javascript"></script>
    <script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
    <script type="text/javascript">

        $(document).ready(function () {

            $("#testForm").validate({
                rules: {
                    "emailAddress": {
                        required: true,
                        email: true,
                        remote: {
                            url: "EmailValidation/checkEmail",
                            type: "post"
                        }
                    }
                },
                messages: {
                    "emailAddress": { remote: "This email address is already in use." }
                }
            });

        });

    </script>
</head>
<body>
    <form action='/EmailValidation' id='testForm'>
        <h1>
            Email Validation</h1>
        <span>Email address</span>
        @Html.TextBox("emailAddress")
        <br />
        <button type="submit">Save</button>        
    </form>
</body>
</html>

Of  special interest in this code is the JQuery "validate" method that takes in a rules object where we can define what the validation rules for a field should be and what messages should be displayed if validation should fail. In particular we can specify that the field should be validated using the "email" rule, which means it will be checked for the correct formatting and we can specify the use of the "remote" rule which means there will be a callback to an action on a controller when performing validation.

The data that jQuery posts back to the controller will be the value of the field that is being validated, in return it will expect a JsonResult with the result being true if it is the validation passes or false if not.  The content of the controller file looks as follows:

using System;
using System.Web.Mvc;
using System.Web.Security;

namespace Blog.Controllers
{
    public class EmailValidationController : Controller
    {

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

        public virtual JsonResult CheckEmail(string emailAddress)
        {
            JsonResult result = new JsonResult();

            result.Data = Membership.FindUsersByEmail(emailAddress).Count == 0;

            return result;
        }

    }
}

In the example above I've used the  ASP.Net Membership service to test if there is a user with that email already in the system, easy!

For more information on the JQuery Validation plugin check out the documentation.