jQuery with ASP.NET

Building rich UI with jQuery and ASP.NET

Custom Validators and Asynchronous Calls to Web Service with jQuery

with one comment


Custom ASP.NET Validators give developers easy way to create validator which is tailored exactly to their needs. Last week I have encountered a scenario in which custom validator was a great solution. I was working on yet another registration form and my job was to validate if username and email address are unique with javascript. I have used Custom Validators for that because I was already using ASP.NET validators so I wanted to stick to one approach for all fields of the registration form. Within client side function I have used jQuery to call web service which will do the validation for me. The trick was to bring it all together and make sure that this solution works with asynchronous calls. Let me show it to you step by step.

1. Create validation Web Service

There are really no tricks regarding the web service. All that you have to remember is to make sure that following lines are uncommented:

// To allow this Web Service to be called from script, using ASP.NET AJAX, uncomment the following line.
[System.Web.Script.Services.ScriptService]

Then add methods which jQuery will call to validate if username and email are unique and therefore available:

[WebMethod]
public bool IsUsernameAvailable(string username)
{
    Thread.Sleep(1000); // for tests only
    return !username.StartsWith("a");
}

[WebMethod]
public bool IsEmailAvailable(string email)
{
    Thread.Sleep(1000); // for tests only
    return email.StartsWith("a");
}

This is of course dummy implementation but I’m sure you get my point here. One thing worth noticing is that Sleep() method on Thread has been used. That’s because in real life scenario validation like this will require a call to a database so inevitably it will be slow. Thanks to Sleep() method I wanted to make sure that response is not instant and this way simulate real life scenario.

2. Custom Validator

Basic ASP.NET code consists of a field where users will enter username and custom validator for it:

<asp:Label ID="lblUsername" runat="server" AssociatedControlID="txbUsername" Text="Username" />
<asp:TextBox ID="txbUsername" runat="server"/>

<asp:CustomValidator
    ID="cuvUsernameAvailable"
    runat="server"
    ControlToValidate="txbUsername"
    Display="Dynamic"
    ClientValidationFunction="ValidateUsername"
    ErrorMessage="Username is not available!"/>

As you can see custom validator requires javascript function ValidateUsername to validate username.

3. Client Side function

Within javascript function I have used jQuery to call web service and this way delegate validation there. jQuery part looks like this:

ValidateUsernameWithWebService = function (username, successFunction) {
    $.ajax({
        type: "POST",
        contentType: "application/json; charset=utf-8",
        url: "/Services/RegistrationDataValidationService.asmx/IsUsernameAvailable",
        data: "{'username':'" + username + "'}",
        dataType: "json",
        async: true,
        success: successFunction,
        error: function (result) {
            alert("Due to unexpected errors validation doesn't work");
        }
    });
}

A few words of explanation:

  • function expects two parameters – username (string) and callback function which will be called after web service invocation.
  • URL to the web service is /Services/RegistrationDataValidationService.asmx, and method which will be invoked is IsUsernameAvailable
  • async parameter is set to true so entire call will be done asynchronously

And finally the ValidateUsername function which will be called by the validator:

// variable to keep result of the last call to web service
var UsernameValidationResult;
// variable to keep information about username which was validated in the last call
var UsernameValidatorLastCheckValue;

ValidateUsername = function (source, args) {

    // detect validation triggered by form submission
    // prevent calls to web service in such scenario, return the previous result
    if (UsernameValidatorLastCheckValue == args.Value) {
        args.IsValid = UsernameValidationResult;
        return;
    }

    // async check with web service
    ValidateUsernameWithWebService(args.Value, function (result) {
        // following 2 lines are here to make sure
        // that on submit validator won't invoke call to webservice
        // it will reuse data from a call which was triggered by onChange event
        UsernameValidationResult = result.d;
        UsernameValidatorLastCheckValue = args.Value;

        // next three lines - inform validator about the result, update display
        source.isvalid = result.d;
        ValidatorUpdateDisplay(source);
        ValidatorUpdateIsValid();
    });
}

This part is a bit messy because you have to realize that validation and therefore this function will be called after entering username (onChange event) and when user click on submit button.

In the first case (onChange event) it’s fine to do the asynchronous call and get results after a second or two. However in case of form submission it’s not an option. It’s also worth noticing that in case of form submission username entered by the user hasn’t change, it was already validated. So it doesn’t make sense to validate it again. And that’s why in the above code I keep results of the last validation in the UsernameValidationResult and UsernameValidatorLastCheckValue variables.

I hope that it all make sense to you, if not then don’t hesitate to leave a comment. I will do my best to refine not clear areas. Also don’t hesitate to leave a comment even if everything is clear but you have a question or maybe something interesting to add. :)

VN:F [1.9.20_1166]
Rating: 8.3/10 (4 votes cast)
Custom Validators and Asynchronous Calls to Web Service with jQuery, 8.3 out of 10 based on 4 ratings

Written by admin

September 11th, 2010 at 9:10 am

One Response to 'Custom Validators and Asynchronous Calls to Web Service with jQuery'

Subscribe to comments with RSS or TrackBack to 'Custom Validators and Asynchronous Calls to Web Service with jQuery'.

  1. Great! Thanks for this code.
    I’d like to make others aware of one very important gotcha (it got me anyway!):

    It’s
    args.IsValid [mixed case]
    and
    sender.isvalid [all lower case]

    VA:F [1.9.20_1166]
    Rating: 0.0/5 (0 votes cast)

    Cathal

    20 Sep 11 at 3:23 pm

Leave a Reply