Create below html document as a basic HTML form.
1: <!DOCTYPE html>
2: <html>
3: <head>
4: <title>jquery validate</title>
5: <!-- javascript will come here -->
6: </head>
7: <body>
8: <form id="userform" action="/Create" method="post">
9:
10: <div><label for="FirstName">First name</label></div>
11: <div><input id="FirstName" name="FirstName" type="text"/></div>
12:
13: <div><label for="LastName">Last name</label></div>
14: <div><input id="LastName" name="LastName" type="text"/></div>
15:
16: <div><label for="Email">Email</label></div>
17: <div><input id="Email" name="Email" type="text"/></div>
18:
19: <div><input type="submit" value="Create" /></div>
20: </form>
21: </body>
22: </html>
And then add below javascript code between "head" tags of the HTML document.
1: <script src="/Scripts/jquery-1.4.4.js" type="text/javascript"></script>
2: <script src="Scripts/jquery.validate.js" type="text/javascript"></script>
3: <script type="text/javascript">
4: $(function () {
5: $("#userform").validate({
6: rules: {
7: FirstName: { required: true, maxlength: 64 },
8: LastName: { required: true, maxlength: 64 },
9: Email: { maxlength: 32,email:true, }
10: }
11: });
12: });
13: </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.
1: <script src="/Scripts/jquery-1.4.4.js" type="text/javascript"></script>
2: <script src="Scripts/jquery.validate.js" type="text/javascript"></script>
3: <script type="text/javascript">
4: $(function () {
5: $("#userform").validate({
6: rules: {
7: FirstName: { required: true, maxlength: 64 },
8: LastName: { required: true, maxlength: 64 },
9: Email: { maxlength: 32,email:true, remote:"/users/checkemailexists" }
10: }
11: });
12: });
13: </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.
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.
1: using System.ComponentModel;
2: using System.ComponentModel.DataAnnotations;
3: using System.Web.Mvc;
4:
5: namespace RemoteValidation.Models
6: {
7: public class UserInfoViewModel
8: {
9: [Required, StringLength(20)]
10: [DisplayName("First name")]
11: public string FirstName { get; set; }
12:
13: [Required, StringLength(20)]
14: [DisplayName("Last name")]
15: public string LastName { get; set; }
16:
17: [Required]
18: [Remote("IsEmailAvailable", "User" /*points to UserController*/)]
19: public string Email { get; set; }
20: }
21: }
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.
1: namespace RemoteValidation.Controllers
2: {
3: public class UserController : Controller
4: {
5: [HttpGet] // GET: /User/Create
6: public ActionResult Create()
7: {
8: return View();
9: }
10:
11: [HttpPost] // POST: /User/Create
12: public ActionResult Create(UserInfoViewModel userInfoViewModel)
13: {
14: // TODO: Add insert logic here
15: // Nothing is required for now, we are not focused on create part,
16: return RedirectToAction("Create");
17: }
18: }
19: }
And now it’s time to create Razor view page, we will create a strongly-typed Razor
view page for UserInfoViewModel model.
1: @model RemoteValidation.Models.UserInfoViewModel
2: @{
3: ViewBag.Title = "Create";
4: Layout = "~/Views/Shared/_Layout.cshtml";
5: }
6: <h2>
7: Create</h2>
8: <script src="@Url.Content("~/Scripts/jquery.validate.min.js")"
type="text/javascript"></script>
9: <script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")"
type="text/javascript"></script>
10: @using (Html.BeginForm())
11: {
12: @Html.ValidationSummary(true)
13: <fieldset>
14: <legend>UserInfoViewModel</legend>
15: <div class="editor-label">
16: @Html.LabelFor(model => model.FirstName)
17: </div>
18: <div class="editor-field">
19: @Html.EditorFor(model => model.FirstName)
20: @Html.ValidationMessageFor(model => model.FirstName)
21: </div>
22: <div class="editor-label">
23: @Html.LabelFor(model => model.LastName)
24: </div>
25: <div class="editor-field">
26: @Html.EditorFor(model => model.LastName)
27: @Html.ValidationMessageFor(model => model.LastName)
28: </div>
29: <div class="editor-label">
30: @Html.LabelFor(model => model.Email)
31: </div>
32: <div class="editor-field">
33: @Html.EditorFor(model => model.Email)
34: @Html.ValidationMessageFor(model => model.Email)
35: </div>
36: <p>
37: <input type="submit" value="Create" />
38: </p>
39: </fieldset>
40: }
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.
<appSettings>
<add key="ClientValidationEnabled" value="true"/>
<add key="UnobtrusiveJavaScriptEnabled" value="true"/>
</appSettings>
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.
1: namespace RemoteValidation.Repositories
2: {
3: public interface IUserRepository
4: {
5: bool EmailExists(string email);
6: }
7: }
8:
9: namespace RemoteValidation.Repositories
10: {
11: public class InMemoryUserRepository : IUserRepository
12: {
13: public bool EmailExists(string email)
14: {
15: //dummy implementation for demo
16: //all emails are available except 'cengiz at cengizhan.com'
17: return email == "cengiz[@]cengizhan.com";
18: }
19: }
20: }
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.
1: using System.Web.Mvc;
2: using RemoteValidation.Models;
3: using RemoteValidation.Repositories;
4:
5: namespace RemoteValidation.Controllers
6: {
7: public class UserController : Controller
8: {
9: private readonly IUserRepository userRepository;
10:
11: public UserController()
12: : this(new InMemoryUserRepository())
13: {
14:
15: }
16:
17: public UserController(IUserRepository userRepository)
18: {
19: this.userRepository = userRepository;
20: }
21:
22: public JsonResult IsEmailAvailable(string email)
23: {
24: if (!userRepository.EmailExists(email))
25: return Json(true, JsonRequestBehavior.AllowGet);
26:
27: return Json("Email address in use", JsonRequestBehavior.AllowGet);
28: }
29:
30: [HttpGet] // GET: /User/Create
31: public ActionResult Create()
32: {
33: return View();
34: }
35:
36: [HttpPost] // POST: /User/Create
37: public ActionResult Create(UserInfoViewModel userInfoViewModel)
38: {
39: // TODO: Add insert logic here
40: return RedirectToAction("Create");
41: }
42: }
43: }
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.
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.
(oRIGINAL aRTICLE AT http://develoq.net)