ASP.NET MVC 3 – Remote Validation with jQuery

17 Jul
2011

jQuery validate plugin provides us to validate HTML forms. jQuery validate plugin disables submitting the for until all specified validation rules are valid. It shows an error label next to invalid field and informs users about input errors.

ASP.NET MVC 3 uses jQuery validation (http://docs.jquery.com/Plugins/validation) for form validations and jQuery validation library has a remote validation feature, using this feature by ASP.NET MVC libraries is really easy but I want to show basic sample with HTML and jQuery.

Create below html document as a basic HTML form.

<!DOCTYPE html>
<html>
<head>
    <title>jquery validate</title>
    <!-- javascript will come here -->
</head>
<body>
    <form id="userform" action="/Create" method="post">
    
    <div><label for="FirstName">First name</label></div>
    <div><input id="FirstName" name="FirstName" type="text"/></div>
    
    <div><label for="LastName">Last name</label></div>
    <div><input id="LastName" name="LastName" type="text"/></div>
    
    <div><label for="Email">Email</label></div>
    <div><input id="Email" name="Email" type="text"/></div>

    <div><input type="submit" value="Create" /></div>
    </form>
</body>
</html>

And then add below javascript code between "head" tags of the HTML document.

<script src="/Scripts/jquery-1.4.4.js" type="text/javascript"></script>
    <script src="Scripts/jquery.validate.js" type="text/javascript"></script>
    <script type="text/javascript">
        $(function () {
            $("#userform").validate({
                rules: {
                    FirstName: { required: true, maxlength: 64 },
                    LastName: { required: true, maxlength: 64 },
                    Email: { maxlength: 32,email:true, }
                }
            });
        });
</script>

This code demonstrates a basic jQuery validation sample, jQuery Validate plugins validates the form before it submitted, if form is valid it submits the form, otherwise form doesn’t get submitted.

As you can see from the sample, basic idea of form validation in jQuery Validate plugin is defining rules in jQuery code and execute them.

But what we do if we need a validation rule that needs some data, business, any input from server side?

jQuery Validate plugin provides a remote validation rules for this kind of requirements. Basically it invokes a server endpoint in validation process and uses that response to decide forms validation.

In this scenario, say, we want to checks availability of email address, we will not validate the form if this email address already registered in our user database.

You just need to add “remote” attribute to validation rules in email for remote validation.

<script src="/Scripts/jquery-1.4.4.js" type="text/javascript"></script>
    <script src="Scripts/jquery.validate.js" type="text/javascript"></script>
    <script type="text/javascript">
        $(function () {
            $("#userform").validate({
                rules: {
                    FirstName: { required: true, maxlength: 64 },
                    LastName: { required: true, maxlength: 64 },
                    Email: { maxlength: 32,email:true, remote:"/users/checkemailexists" }
                }
            });
        });
</script>

When jQuery Validate plugin validates our form it will call /users/checkemailexists endpoint with a querystring that contains current email input, jquery validates the form when we are typing, after each key press. In this sample jQuery know this field is an email input (email:true rule provides that) and it will not call remote endpoint until we enter a valid text for email pattern that jQuery checks.

jquery-remote-validate1

As you can see from below screenshot jQuery makes three calls to checkemailexists endpoint with cengiz@cengizhan.c, cengiz@cengizhan.co and lastly with my full email with .com extension. You will see one request for each keypress If you remove email:true rule from rules.

That shows us it’s really important to run client side rules before remote call, and yes order is important in rules definition.

if you change the rule like below it will first make remote call and validate the input against email regex pattern.

Email: { maxlength: 32, remote:"/users/checkemailexists", email:true}

For now, I haven’t created an endpoint for validation of email address so it returns and 404 Not Found error message and jQuery accepts it as invalid.

I want to move to ASP.NET MVC part and create that endpoint afterwards.

We will use ASP.NET Razor Page Engine to create all HTML outputs and validation logics.

First create a view model under the model folder in your ASP.NET MVC 3 project.

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

namespace RemoteValidation.Models
{
    public class UserInfoViewModel
    {
        [Required, StringLength(20)]
        [DisplayName("First name")]
        public string FirstName { get; set; }

        [Required, StringLength(20)]
        [DisplayName("Last name")]
        public string LastName { get; set; }

        [Required]
        [Remote("IsEmailAvailable", "User" /*points to UserController*/)]
        public string Email { get; set; }
    }
}

As you can notice from above code snippet Remote attributes defines remote validation settings for Email property, it will call IsEmailAvailable action on UserController. We will pass this step for now, firstly we will create and endpoint named as “Create” under “UserController”. Create a ”UserController” class under controllers folder.

namespace RemoteValidation.Controllers
{
    public class UserController : Controller
    {
        [HttpGet]  // GET: /User/Create
        public ActionResult Create()
        {
            return View();
        }

        [HttpPost]  // POST: /User/Create
        public ActionResult Create(UserInfoViewModel userInfoViewModel)
        {
            // TODO: Add insert logic here
            // Nothing is required for now, we are not focused on create part,
            return RedirectToAction("Create");
        }
    }
}

And now it’s time to create Razor view page, we will create a strongly-typed Razor view page for UserInfoViewModel model.

@model RemoteValidation.Models.UserInfoViewModel
@{
    ViewBag.Title = "Create";
    Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>
    Create</h2>
<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>
@using (Html.BeginForm())
{
    @Html.ValidationSummary(true)
    <fieldset>
        <legend>UserInfoViewModel</legend>
        <div class="editor-label">
            @Html.LabelFor(model => model.FirstName)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.FirstName)
            @Html.ValidationMessageFor(model => model.FirstName)
        </div>
        <div class="editor-label">
            @Html.LabelFor(model => model.LastName)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.LastName)
            @Html.ValidationMessageFor(model => model.LastName)
        </div>
        <div class="editor-label">
            @Html.LabelFor(model => model.Email)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.Email)
            @Html.ValidationMessageFor(model => model.Email)
        </div>
        <p>
            <input type="submit" value="Create" />
        </p>
    </fieldset>
}

ASP.NET MVC 3 support unobtrusive Javascript for jQuery validation plugin. To activate this you need to enable a setting from web config and add jquery.validate.unobtrusive.min.js script file (obviously min part is optional) to your web page.

web.config setting

<appSettings>
    <add key="ClientValidationEnabled" value="true"/> 
    <add key="UnobtrusiveJavaScriptEnabled" value="true"/> 
  </appSettings>

Now let’s run the application and see what happens when jQuery Validate plugin trying to validate.

jquery-remote-validate2

Request is successfully made by jQuery Validate plugin, let’s create the action for remote validation.

I will create a basic repository for users and inject it to the controller and will create the controller method.

Let’s create repository interface and dummy in-memory repository.

namespace RemoteValidation.Repositories
{
    public interface IUserRepository
    {
        bool EmailExists(string email);
    }
}

namespace RemoteValidation.Repositories
{
    public class InMemoryUserRepository : IUserRepository
    {
        public bool EmailExists(string email)
        {
            //dummy implementation for demo
            //all emails are available except 'cengiz at cengizhan.com'
            return email == "cengiz[@]cengizhan.com";
        }
    }
}

InMemoryUserRepository.EmailExists will return false for all emails except one sample email address, my email address.

Now inject repository to controller and create controller action method.

using System.Web.Mvc;
using RemoteValidation.Models;
using RemoteValidation.Repositories;

namespace RemoteValidation.Controllers
{
    public class UserController : Controller
    {
        private readonly IUserRepository userRepository;

        public UserController()
            : this(new InMemoryUserRepository())
        {

        }

        public UserController(IUserRepository userRepository)
        {
            this.userRepository = userRepository;
        }

        public JsonResult IsEmailAvailable(string email)
        {
            if (!userRepository.EmailExists(email))
                return Json(true, JsonRequestBehavior.AllowGet);

            return Json("Email address in use", JsonRequestBehavior.AllowGet);
        }

        [HttpGet]  // GET: /User/Create
        public ActionResult Create()
        {
            return View();
        }

        [HttpPost]  // POST: /User/Create
        public ActionResult Create(UserInfoViewModel userInfoViewModel)
        {
            // TODO: Add insert logic here
            return RedirectToAction("Create");
        }
    }
}

IsEmailAvailable action methods will return validation  result, true in available case, error message in not available case.

quote from jQuery web page

The response is evaluated as JSON and must be true for valid elements, and can be any false, undefined or null for invalid elements, using the default message; or a string, eg. "That name is already taken, try peter123 instead"to display as the error message.

Let’s see HTTP traffic with invalid and valid results.

jquery-remote-validate3

 

jquery-remote-validate4

It’s done. jQuery will call endpoint and get the JSON response from action method to decide validation. This how remote validation works in ASP.NET MVC. For more information about jQuery Validate plugin’s remote validation feature go to jQuery web site.



4 Responses to ASP.NET MVC 3 – Remote Validation with jQuery

Avatar

ramakrishnan

October 20th, 2011 at 3:53 pm

thanks a ton.
its helped me a lot.
nice article/post

Avatar

Awadhendra

April 1st, 2012 at 9:41 am

Hi,
Nice approach, you explained very well about validation in ASP.NET MVC3. I am a new learner in ASP.NET MVC3 and this article is great helpful for me. I learned about validation and I compare it from ASP.NET then I found that it is very easy to implement it in MVC. We can implement it in one place and it react in both place which is server side and client side. It’s really good to know it. I had explained few basic things about validation in ASP.NET MVC3 using razor view engine at following url

http://dabbu-csharphelp.blogspot.in/2012/01/validation-in-asp.html

I think this is useful for beginners who wnt to know basic of validation in ASP.NET MVC3. Thanks for sharing such a useful articlde on validation.

Thanks.

Avatar

Blake Niemyjski

November 15th, 2012 at 4:02 pm

The best documentation I’ve seen so far for this feature. Are you going to post any updates to this article for mvc4?

Avatar

Somebody

December 11th, 2012 at 4:48 pm

Thank you. Helped me a lot

Comment Form

top