ASP.NET MVC 2: Validating MVC

Exclusive offer: get 80% off this eBook here
ASP.NET MVC 2 Cookbook

ASP.NET MVC 2 Cookbook — Save 80%

Over 70 clear and incredibly effective recipes to get the most out of the many tools and features of the ASP.NET MVC framework

₨924.00    ₨184.80
by Andrew Siemer Richard Kimber | January 2011 | .NET Cookbooks Microsoft

Validation is the key to any application that accepts input of any kind, but where should it be implemented—on the client where it is most responsive, in the business logic where it is most central, or in the data layer where it is most secure? ASP.NET MVC provides a simple yet powerful framework for defining validation from a central location that is decoupled from the data layer; validation that makes use of client scripting without being dependent on it; and with all this, keeping the validation DRY.

In this article by Andrew Siemer and Richard Kimber, authors of ASP.NET MVC 2 Cookbook, we will cover:

  • Basic input validation
  • Data annotations
  • Client-side validation with jQuery
  • Custom validators
  • Remote validation with jQuery

 

ASP.NET MVC 2 Cookbook

ASP.NET MVC 2 Cookbook

A fast-paced cookbook with recipes covering all that you wanted to know about developing with ASP.NET MVC

  • Solutions to the most common problems encountered with ASP.NET MVC development
  • Build and maintain large applications with ease using ASP.NET MVC
  • Recipes to enhance the look, feel, and user experience of your web applications
  • Expand your MVC toolbox with an introduction to lots of open source tools
  • Part of Packt's Cookbook series: Each recipe is a carefully organized sequence of instructions to complete the task as efficiently as possible
        Read more about this book      

(For more resources on .NET, see here.)

Introduction

ASP.NET MVC provides a simple, but powerful, framework for validating forms. In this article, we'll start by creating a simple form, and then incrementally extend the functionality of our project to include client-side validation, custom validators, and remote validation.

Basic input validation

The moment you create an action to consume a form post, you're validating. Or at least the framework is. Whether it is a textbox validating to a DateTime, or checkbox to a Boolean, we can start making assumptions on what should be received and making provisions for what shouldn't. Let's create a form.

How to do it...

  1. Create an empty ASP.NET MVC 2 project and add a master page called Site.Master to Views/Shared.
  2. In the models folder, create a new model called Person. This model is just an extended version of the Person class.

    Models/Person.cs:

    public class Person {
    [DisplayName("First Name")]
    public string FirstName { get; set; }
    [DisplayName("Middle Name")]
    public string MiddleName { get; set; }
    [DisplayName("Last Name")]
    public string LastName { get; set; }
    [DisplayName("Birth Date")]
    public DateTime BirthDate { get; set; }
    public string Email { get; set; }
    public string Phone { get; set; }
    public string Postcode { get; set; }
    public string Notes { get; set; }
    }

  3. Create a controller called HomeController and amend the Index action to return a new instance of Person as the view model.

    Controllers/HomeController.cs:

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

  4. Build and then right-click on the action to create an Index view. Make it an empty view that strongly types to our Person class.
  5. Create a basic form in the Index view.

    Views/Home/Index.aspx:

    <% using (Html.BeginForm()) {%>
    <%: Html.EditorForModel() %>
    <input type="submit" name="submit" value="Submit" />
    <% } %>

  6. We'll go back to the home controller now to capture the form submission. Create a second action called Index, which accepts only POSTs.

    Controllers/HomeController.cs:

    [HttpPost]
    public ActionResult Index(...

  7. At this point, we have options. We can consume our form in a few different ways, let's have a look at a couple of them now:

    Controllers/HomeController.cs (Example):

    // Individual Parameters
    public ActionResult Index(string firstName, DateTime birthdate...

    // Model
    Public ActionResult Index(Person person) {

  8. Whatever technique you choose, the resolution of the parameters is roughly the same. The technique that I'm going to demonstrate relies on a method called UpdateModel. But first we need to differentiate our POST action from our first catch-all action. Remember, actions are just methods, and overrides need to take sufficiently different parameters to prevent ambiguity. We will do this by taking a single parameter of type FormCollection, though we won't necessarily make use of it.

    Controllers/HomeController.cs:

    [HttpPost]
    public ActionResult Index(FormCollection form) {
    var person = new Person();

    UpdateModel(person);

    return View(person);
    }

    The UpdateModel technique is a touch more long-winded, but comes with advantages. The first is that if you add a breakpoint on the UpdateModel line, you can see the exact point when an empty model becomes populated with the form collection, which is great for demonstration purposes.
    The main reason I go back to UpdateModel time and time again, is the optional second parameter, includeProperties. This parameter allows you to selectively update the model, thereby bypassing validation on certain properties that you might want to handle independently.

  9. Build, run, and submit your form. If your page validates, your info should be returned back to you. However, add your birth date in an unrecognized format and watch it bomb. UpdateModel is a temperamental beast.

    ASP.NET MVC 2: Validating MVC

  10. Switch your UpdateModel for TryUpdateModel and see what happens. TryUpdateModel will return a Boolean indicating the success or failure of the submission. However, the most interesting thing is happening in the browser.

    ASP.NET MVC 2: Validating MVC

How it works...

With ASP.NET MVC, it sometimes feels like you're stripping the development process back to basics. I think this is a good thing; more control to render the page you want is good. But there is a lot of clever stuff going on in the background, starting off with Model Binders.

When you send a request (GET, POST, and so on) to an ASP.NET MVC application, the query string, route values and the form collection are passed through model binding classes, which result in usable structures (for example, your action's input parameters). These model binders can be overridden and extended to deal with more complex scenarios, but since ASP.NET MVC2, I've rarely made use of this. A good starting point for further investigation would be with DefaultModelBinder and IModelBinder.

What about that validation message in the last screenshot, where did it come from? Apart from LableFor and EditorFor, but we also have ValidationMessageFor. If the model binders fail at any point to build our input parameters, the model binder will add an error message to the model state. The model state is picked up and displayed by the ValidationMessageFor method, but more on that later.

ASP.NET MVC 2 Cookbook Over 70 clear and incredibly effective recipes to get the most out of the many tools and features of the ASP.NET MVC framework
Published: January 2011
eBook Price: ₨924.00
Book Price: ₨1,540.00
See more
Select your format and quantity:
        Read more about this book      

(For more resources on .NET, see here.)

Data annotations

Okay, given the minimal effort we put into creating our form, getting that validation message on the birth date was impressive. You would also get an error message if you didn't send a date at all because DateTime cannot be null.

The question that we will answer in this recipe however, is how do we add validation that is not implied by type? One way is to use data annotations. Data annotations are a collection of attributes that allow you to describe your model in terms of what is required, or what a property might be used for, among other things.

How to do it...

  1. Starting from our previous recipe, let's go to our Person model and make the following amendments:

    Models/Person.cs:

    public class Person {
    [DisplayName("First Name"), StringLength(50)]
    public string FirstName { get; set; }
    [DisplayName("Middle Name"), StringLength(50)]
    public string MiddleName { get; set; }
    [DisplayName("Last Name"), StringLength(50), Required]
    public string LastName { get; set; }
    [DisplayName("Birth Date"), DataType(DataType.Date)]
    public DateTime BirthDate { get; set; }
    [DataType(DataType.EmailAddress), Required]
    public string Email { get; set; }
    public string Phone { get; set; }
    public string Postcode { get; set; }
    [DataType(DataType.MultilineText)]
    public string Notes { get; set; }
    }

  2. Build the project and then reload the form to see the changes. We can already see a neater date (Birth Date) and a text area instead of a textbox (Notes). Submit though, and we start getting feedback as well.

    ASP.NET MVC 2: Validating MVC

  3. Validation attributes such as Required and StringLength inherit from ValidationAttribute, which contains additional properties that allow you to customize the error message or attach the attribute to a resource. In the following screenshot, I've amended the error message of the MiddleName property.

How it works...

The default model binder in ASP.NET MVC uses reflection to interrogate target types for attributes that fall under the namespace DataAnnotations. Using the additional metadata provided by the attributes, the model binder can generate a more comprehensive set of tests.

Client-side validation with jQuery

We're already running quite a tight ship with our form, but it's a little frustrating to receive the error messages only after we submit the form. Think about thousands of people constantly submitting incorrect data to your site. It's an unnecessary use of your valuable resources. Client-side validation goes some way to prevent this, but used to be a real bind to implement; with ASP.NET MVC though, it's remarkably easy.

Getting ready

Up until about ASP.NET MVC 2 RC, there were two options for implementing client-side validation—Microsoft Ajax and jQuery. Of the two, the jQuery option was mysteriously absent from the final release. It will be the jQuery option that we will focus on in this recipe. Beyond the jQuery files already contained within any new ASP.NET MVC 2 project, this recipe has a requirement for the somewhat elusive jQuery connector. I've given up trying to track down the file's permanent residence, so will simply say that it is included within the book's source code, and can be tracked down (with some effort) on Google by searching for MicrosoftMvcJQueryValidation.js. You can also download an amended version from http://blog.dogma.co.uk.

How to do it...

  1. Starting from the previous recipe, let's add a call to Html.EnableClientValidation() above our form in Views/Home/Index.aspx.

    Views/Home/Index.aspx:

    <% Html.EnableClientValidation(); %>
    <% using (Html.BeginForm()) {%>

  2. Open up your Site.Master file and add the following three lines above the closing body tag, assuming that you added the connector file to the root of your Scripts folder.

    Views/Shared/Site.Master:

    <script src='//dgdsbygo8mp3h.cloudfront.net/sites/default/files/blank.gif' data-original="/Scripts/jquery-1.4.1.min.js"
    type="text/javascript"></script>
    <script src='//dgdsbygo8mp3h.cloudfront.net/sites/default/files/blank.gif' data-original="/Scripts/jquery.validate.min.js"
    type="text/javascript"></script>
    <script src='//dgdsbygo8mp3h.cloudfront.net/sites/default/files/blank.gif' data-original="/Scripts/MicrosoftMvcJQueryValidation.js"
    type="text/javascript"></script>

  3. Build and run your project, then submit your form. Unless you've filled in all the required fields, you wouldn't be able to make a submission. jQuery, with the help of our connector (MicrosoftMvcJQueryValidation.js), has prevented the POST. What's more, if you start correcting the mistakes, the error messages will disappear without having to attempt resubmission.

How it works...

In the first step, we added a call to an HTML helper called EnableClientValidation. The EnableClientValidation method should be added just above the targeted form and it basically tells the form to render some extra information. The extra information is a JSON (JavaScript Object Notation) map containing all the validation conditions for the form within a script block. The script block is placed directly beneath the form and attaches the map to a window object called mvcClientValidationMetadata. Have a look at the HTML source of your form for a complete example.

Home/Index (View Source):

if (!window.mvcClientValidationMetadata) {
window.mvcClientValidationMetadata = []; }
window.mvcClientValidationMetadata.push({ "Fields": [{
"FieldName": "FirstName",
"ReplaceValidationMessageContents": true,
"ValidationMessageId": "FirstName_validationMessage",
"ValidationRules": [{

"ErrorMessage": "The field First Name must be a
string with a maximum length of 50.",
"ValidationParameters": {
"minimumLength": 0, "maximumLength": 50 },
"ValidationType": "stringLength"
}]
},
...

The validation itself is handled by a very robust jQuery plug-in called jQuery Validation. At this point though, the validation plug-in needs to be initiated and, as the mvcClientValidationMetdata object is a Microsoft invention that means nothing to jQuery, we need a bridge. Enter MicrosoftMvcJQueryValidation.js (the connector). This file consumes the JSON map and reformats it as an options object that the validation plug-in can understand. The connector then calls the validation plug-in into action.

So far, we have mirrored validation on the client and server with a small amount of effort. What else can we do?

Custom validators

We can create our own validation rules. I've got a couple of issues with our code so far.

  • We've told ASP.NET MVC that our email field is an e-mail field, but I can type in any old junk.
  • I'm British (that is not the issue), so I've got a postcode and I want to validate it!

I've already mentioned the ValidationAttribute class and some of the attributes that inherit from it, another is RegularExpressionAttribute. We'll derive a couple of attributes from the RegularExpressionAttribute to resolve my two immediate issues.

How to do it...

  1. From our last recipe, we'll create a new folder called Helpers and a class within, called Attributes.
  2. In Attributes.cs, create a new class called EmailAttribute, which inherits from RegularExpressionAttribute.
  3. Override the base constructor with the following code. Of particular note here is the regular expression used, ^[a-zA-Z0-9._%+-]+@(?:[a-zA-Z0-9-]+\.)+[a-zA-Z]{2,6}$, which is passed in as the sole parameter. We then provide a default error message within the constructor.

    Helpers/Attributes.cs:

    public class EmailAttribute : RegularExpressionAttribute {
    public EmailAttribute() : base(
    @"^[a-zA-Z0-9._%+-]+@(?:[a-zA-Z0-9-]+\.)+[a-zA-Z]{2,6}$") {
    ErrorMessage = "Email is invalid";
    }
    }

  4. We'll now switch our attention to the Person model in the models folder. Make the following adjustment, remembering to resolve your namespaces. We're saying that this property should conform to the regular expression specified.

    Models/Person.cs:

    public DateTime BirthDate { get; set; }
    [DataType(DataType.EmailAddress), Required, Email]
    public string Email { get; set; }

  5. Build and run your project. Fill out the form and submit with and without a correctly formatted e-mail address. Your first observation should be that it is not working on the client-side, but is on the server.

  6. Our e-mail validation is not working on the client because ASP.NET MVC doesn't know what an EmailAttribute is. The framework does know what a RegularExpressionAttribute is, though. So, within the Global.asax.cs file, our final step for e-mail validation will be to tell ASP.NET MVC to make this connection.

    Global.asax.cs:

    protected void Application_Start() {
    AreaRegistration.RegisterAllAreas();

    RegisterRoutes(RouteTable.Routes);

    DataAnnotationsModelValidatorProvider.RegisterAdapter(
    typeof(EmailAttribute),
    typeof(RegularExpressionAttributeAdapter));
    }

  7. Build your project and reload your form. You should now have client-side e-mail validation.
  8. The process required for a postcode validation is almost identical, except this time you use a different regular expression.

    Helpers/Attributes.cs:

    ([Gg][Ii][Rr] 0[Aa]{2})|((([A-Za-z][0-9]{1,2})|(([A-Za-z][A-Ha-
    hJ-Yj-y][0-9]{1,2})|(([A-Za-z][0-9][A-Za-z])|([A-Za-z][A-Ha-hJ-
    Yj-y][0-9]?[A-Za-z])))) {0,1}[0-9][A-Za-z]{2})

  9. Follow each of the steps that we did for our e-mail validation and you should end with something like this:

How it works...

We could have just used a vanilla RegularExpressionAttribute to satisfy both cases. But what we have now is two very useful attributes that can be reapplied across multiple models and projects. For the client-side validation to work, there needs to be a translation between the server and client environments. The translation happens in an AttributeAdapter that is registered in the DataAnnotationsModelValidatorProvider. It is these two components that ultimately decide the shape of the JSON map identified in the last recipe. We cover this concept in more detail in the next recipe.

ASP.NET MVC 2 Cookbook Over 70 clear and incredibly effective recipes to get the most out of the many tools and features of the ASP.NET MVC framework
Published: January 2011
eBook Price: ₨924.00
Book Price: ₨1,540.00
See more
Select your format and quantity:
        Read more about this book      

(For more resources on .NET, see here.)

Remote validation with jQuery

In a lot of cases, validation is a static formula, something definable like a formula or regular expression. Sometimes however, validation requires an external source (like a database). In cases like this, putting the logic in an attribute is possible but not always ideal. And what happens to the client-side? It's not so easy to tell the browser to connect to a database before allowing a form submission. Well, it's actually a lot easier than I thought.

Getting ready

In this recipe, we'll think of our form as a registration form. We've been getting a lot of duplicate registrations, so we'd like to prevent users from registering an e-mail address more than once.

How to do it...

  1. Start from our last recipe and open up the home controller.
  2. Add the following method called IsEmailAlreadyRegistered to the top of the home controller class. This method will act as a list of e-mails that have already been registered. You will need to add a reference to the System.Linq namespace.

    Controllers/HomeController.cs:

    private bool IsEmailAlreadyRegistered(string email) {
    return new string[] { "test@test.com", "example@example.com",
    "richard@dogma.co.uk" }.Contains(email);
    }

  3. Now we need to add some code to the Index action (the one that accepts only POSTs) to validate against our list of e-mail addresses. Before we attempt to validate against our e-mail list, we'll make sure that the rest of the model has validated successfully. If the e-mail does already exist, we'll add an error message to the ModelState object. Add the following code after the TryUpdateModel call.

    Controllers/HomeController.cs:

    if (ModelState.IsValid && IsEmailAlreadyRegistered(person.Email))
    {
    var propertyName = "email";
    ModelState.AddModelError(propertyName, "Email address is already
    registered");
    ModelState.SetModelValue(propertyName,
    ValueProvider.GetValue(propertyName));
    }

  4. The ModelState object represents the state of the models before they're sent to the view. The model state contains the validation message and the current values. If you provide a model error without a model value, you can run into unexpected errors further down the line.

  5. Let's see how this works. Build and run the project.

  6. We should now be preventing duplicate registrations on the server, but ideally, we'd like this on the client as well. We'll do this by using remote validation, which generally involves an Ajax call to the server. First, we need to tell ASP.NET what remote validation is. Let's create a new attribute in our Attributes.cs file called RemoteAttribute.

    Helpers/Attributes.cs:

    public class RemoteAttribute : ValidationAttribute { }

  7. jQuery's validation plug-in will need a URL to connect to, in order to establish whether the e-mail has already been registered or not; so we'll add a URL property. Also, because this attribute is not going to be validating on the server, we'll override the IsValid method to always return true.

    Helpers/Attributes.cs:

    public class RemoteAttribute : ValidationAttribute {
    public string Url { get; set; }

    public RemoteAttribute() {
    ErrorMessage = "Email address is already registered";
    }

    public override bool IsValid(object value) {
    return true;
    }
    }

  8. Now before we go and decorate our Person model with our shiny new attribute, we need a URL for our client validation to validate against. Go back to the home controller and create a new action called EmailCheck.

    Controllers/HomeController.cs:

    public ActionResult EmailCheck(string email) {
    return Json(!IsEmailAlreadyRegistered(email),
    JsonRequestBehavior.AllowGet);
    }

  9. We can now decorate our model. Open up the Person class and make the following amendment.

    Models/Person.cs:

    [DataType(DataType.EmailAddress), Required, Email,
    Remote(Url = "/home/emailcheck")]
    public string Email { get; set; }

  10. At this stage we have an attribute, a URL, and we've decorated our model. Now we need an attribute adapter. Create a new class in your Helpers folder called RemoteAttributeAdapter, which will inherit from DataAnnotationsModelValidator<RemoteAttribute>.

    Helpers/RemoteAttributeAdapter.cs:

    public class RemoteAttributeAdapter :
    DataAnnotationsModelValidator<RemoteAttribute> { }

  11. DataAnnotationsModelValidator<> doesn't have a parameter-less constructor, so we'll need to create a new constructor for our class.

    Helpers/RemoteAttributeAdapter.cs:

    public class RemoteAttributeAdapter :

    DataAnnotationsModelValidator<RemoteAttribute> {

    public RemoteAttributeAdapter(ModelMetadata metadata,
    ControllerContext context, RemoteAttribute attribute) :
    base(metadata, context, attribute) { }
    }

  12. I mentioned in the last recipe that the adapter had its part to play in what was rendered on the client; this happens in a method called GetClientValidationRules. You'll see from the following code that we can add custom parameters to relate to our new attribute.

    Helpers/RemoteAttributeAdapter.cs:

    public class RemoteAttributeAdapter :
    DataAnnotationsModelValidator<RemoteAttribute> {
    public RemoteAttributeAdapter(ModelMetadata metadata,
    ControllerContext context, RemoteAttribute attribute) :
    base(metadata, context, attribute) { }

    public override IEnumerable<ModelClientValidationRule>
    GetClientValidationRules() {
    var rule = new ModelClientValidationRule {
    ErrorMessage = ErrorMessage,
    ValidationType = "remote"
    };
    rule.ValidationParameters["url"] = Attribute.Url;
    rule.ValidationParameters["type"] = "get";

    return new[] { rule };
    }
    }

    GetClientValidationRules returns a collection of ModelClientValidationRules. These rules are special because when serialized, they make up the structure of the JSON map that we identified two recipes ago, called mvcClientValidationMetdata.

  13. In the last step, we created a rule with a validation type of remote. Remote validation is baked straight into the jQuery validation plug-in—the Microsoft connector (MicrosoftMvcJQueryValidation.js) however, has no idea what remote validation is. So, we will need to make some changes. Open up the MicrosoftMvcJQueryValidation.js in your Scripts folder.
  14. The connector file is a series of functions that respond to different validation types. Our first job will be to create a function to respond to the remote validation type (or rule). When you look at the following code, you will see that it acts like a mirror for the GetClientValidationRules method that we created a second ago. It consumes the custom parameter's set on the server and produces a jQuery-friendly options object.

    Scripts/MicrosoftMvcJQueryValidation.js:

    function __MVC_ApplyValidator_Remote(object, validationParameters,
    fieldName) {
    var obj = object["remote"] = {};
    var props = validationParameters.additionalProperties;

    obj["url"] = validationParameters.url;
    obj["type"] = validationParameters.type;

    if (props) {
    var data = {};

    for (var i = 0, l = props.length; i < l; ++i) {
    var param = props[i];
    data[props[i]] = function () {
    return $("#" + param).val();
    }
    }

    obj["data"] = data;
    }
    }

  15. We're almost there. We just need to connect the remote validation type to our function, as well as pass the correct parameters. Our new function makes use of the name of the field being validated. The factory method (__MVC_CreateRulesForField) that associates the validation type to the function currently has no knowledge of this, so we'll need to pass it in as an additional parameter.

    Scripts/MicrosoftMvcJQueryValidation.js:

    function __MVC_CreateValidationOptions(validationFields) {
    var rulesObj = {};
    for (var i = 0; i < validationFields.length; i++) {
    var validationField = validationFields[i];
    var fieldName = validationField.FieldName;
    rulesObj[fieldName] =
    __MVC_CreateRulesForField(validationField, fieldName);
    }
    return rulesObj;
    }

  16. Now we want to tell the factory method to make use of the additional parameter, and apply it to our new function.

    Scripts/MicrosoftMvcJQueryValidation.js:

    function __MVC_CreateRulesForField(validationField, fieldName) {
    var validationRules = validationField.ValidationRules;
    // hook each rule into jquery
    var rulesObj = {};
    for (var i = 0; i < validationRules.length; i++) {
    var thisRule = validationRules[i];
    switch (thisRule.ValidationType) {
    case "range":
    __MVC_ApplyValidator_Range(rulesObj,
    thisRule.ValidationParameters["minimum"],
    thisRule.ValidationParameters["maximum"]);
    break;

    case "regularExpression":
    __MVC_ApplyValidator_RegularExpression(rulesObj,
    thisRule.ValidationParameters["pattern"]);
    break;

    case "required":
    __MVC_ApplyValidator_Required(rulesObj);
    break;

    case "stringLength":
    __MVC_ApplyValidator_StringLength(rulesObj,
    thisRule.ValidationParameters["maximumLength"]);
    break;

    case "remote":
    __MVC_ApplyValidator_Remote(rulesObj,
    thisRule.ValidationParameters, fieldName);
    break;

    default:
    __MVC_ApplyValidator_Unknown(rulesObj,
    thisRule.ValidationType,
    thisRule.ValidationParameters);
    break;
    }
    }

    return rulesObj;
    }

  17. If we build and run this form in Firefox (with FireBug switched on), we should be able to see our remote validation in action.

How it works...

The validation plug-in of jQuery is a comprehensive collection of rules, which can be triggered in any number of ways. The most common approach is through the use of class names applied to the input field; where a textbox decorated with the class required would result in the surrounding form not being able to submit without the said textbox being filled in. Another way to initiate the validation plug-in is through the use of an options object. The options object is a schema for how the form should be validated.

ASP.NET MVC's client-side validation was not built with jQuery's specific schema in mind, so the MicrosoftMvcJQueryValidation.js file was written to bridge the JavaScript injected by ASP.NET MVC (mvcClientValidationMetdata) with the jQuery options object, then initializing the validation plug-in.

Scripts/MicrosoftMvcJQueryValidation.js:

function __MVC_EnableClientValidation(validationContext) {
// this represents the form containing elements to be validated
var theForm = $("#" + validationContext.FormId);

...

var options = {

errorClass: "input-validation-error",
...
$(messageSpan).removeClass("field-validation-error");
}
};

// register callbacks with our AJAX system
var formElement =
document.getElementById(validationContext.FormId);
var registeredValidatorCallbacks =
formElement.validationCallbacks;
if (!registeredValidatorCallbacks) {
registeredValidatorCallbacks = [];
formElement.validationCallbacks = registeredValidatorCallbacks;
}
registeredValidatorCallbacks.push(function () {
theForm.validate();
return theForm.valid();
});

theForm.validate(options);
}

Baked into jQuery's validation plug-in is this concept of remote validation. Remote validation is validation where not all the variables are known at implementation, so there is a requirement to source that information from a remote location. When dealing with remote validation it is preferable to try and retrieve any information without disrupting the user's workflow; for this reason we use an Ajax request to the server. As the user types in his/her e-mail address, the client-side script silently fires off requests to our URL (or endpoint) to unobtrusively validate the input.

We enabled jQuery's remote validation functionality by passing through the URL of an action, which will return a Boolean based on the existence of the entered e-mail within our dummy method. jQuery took care of the rest with a simple GET request to our endpoint.

Summary

Validation was something I didn't particularly enjoy in ASP.NET web forms, but now relish in ASP.NET MVC. It is another great example of the extensibility of the new framework.


Further resources on this subject:


About the Author :


Andrew Siemer

Andrew Siemer is currently the enterprise architect at OTX Research. He has worked as a software engineer, enterprise architect, trainer, and author since 1998 when he got out of the Army. Andrew has consulted with many companies on the topics of e-commerce, social networking, and business systems. To name a few, he has worked with eUniverse (AllYouCanInk.com), PointVantage (MyInks.com), Callaway Golf (CallawayConnect.com), Guidance Software (GuidanceSoftware.com), and Intermix Media (Grab.com, AmericanIdol.com, FoxSports.com, FlowGo.com). In addition to his daily duties he also offers various classes in .NET, C#, and other web technologies to local students in his area as well as blogging in his *free* time.

Richard Kimber

Richard Kimber has been working with web technologies for over 15 years. Primarily ASP.NET developer, Richard has worked in a broad range of development environments, from the financial services industry to new media and marketing. He now runs a web and mobile consultancy company called Dogma Creative with his wife Katie.

Books From Packt


.NET Compact Framework 3.5 Data Driven Applications
.NET Compact Framework 3.5 Data Driven Applications

DotNetNuke 5.4 Cookbook
DotNetNuke 5.4 Cookbook

NHibernate 3.0 Cookbook
NHibernate 3.0 Cookbook

Microsoft Azure: Enterprise Application Development
Microsoft Azure: Enterprise Application Development

Microsoft Windows Workflow Foundation 4.0 Cookbook
Microsoft Windows Workflow Foundation 4.0 Cookbook

WCF 4.0 Multi-tier Services Development with LINQ to Entities
WCF 4.0 Multi-tier Services Development with LINQ to Entities

Mastering phpMyAdmin 3.3.x for Effective MySQL Management
Mastering phpMyAdmin 3.3.x for Effective MySQL Management

Microsoft Windows Communication Foundation 4.0 Cookbook for Developing SOA Applications
Microsoft Windows Communication Foundation 4.0 Cookbook for Developing SOA Applications


Code Download and Errata
Packt Anytime, Anywhere
Register Books
Print Upgrades
eBook Downloads
Video Support
Contact Us
Awards Voting Nominations Previous Winners
Judges Open Source CMS Hall Of Fame CMS Most Promising Open Source Project Open Source E-Commerce Applications Open Source JavaScript Library Open Source Graphics Software
Resources
Open Source CMS Hall Of Fame CMS Most Promising Open Source Project Open Source E-Commerce Applications Open Source JavaScript Library Open Source Graphics Software