An Asyncronous Callback with the Microsoft AJAX Library (aka Atlas)

Sep 19, 2006 by

In this post I will present an example asynchronous callback to a hosted web service using Microsofts Atlas (August 06 CTP), which will be known as the Microsoft Ajax Library going forward.  The example will highlight two things:

  • How to assemble a custom object and prepare it for asynchronous callback
  • How to handle various responses from the called web service

For those out there that have been working with Atlas for awhile now, this post may seem like old hat, but at the very least it can serve as a refresher.  For those that have little experience with Atlas thus far, hopefully this ‘tutorial’ (I use the term loosely) will serve to bolster your interest.  The post assumes you’ve downloaded and installed the Atlas client-side libraries and templates from the Atlas website.

First Things First: The Service

In this example, I’ll show how to pass custom objects in your callbacks, greatly expanding the capability of client-side code.  To do this, we’ll assume you have a server-side class called Person with two members: string Name, and int Age.  You’ll have created a new web service that we’ll call MyService.asmx (the MyService class) where you will include your WebMethods, like this:

[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
public class MyService : System.Web.Services.WebService
{
    [WebMethod]
    public Person SavePerson(Person myPerson)
    {
        try
        {
            //code to add myPerson to the database will go here
            //and on success, we return the resulting Person object
            return newPerson;                        
        }
        catch(Exception e)
        {
            return null;
        }        
    }        
}
public class Person { … }
 

What we’ve setup here is a web service containing the SavePerson web method with a return type of Person that also accepts a Person object as its only parameter.  Atlas has built-in handlers for various unexpected service problems such as timeout, error, and so on that would disrupt the roundtrip of the callback (more on this further down).  If the callback has a successful roundtrip, but the service failed to save the Person object to the database, we can catch that too on the client-side because the webmethod SavePerson will return null.  Now we assemble user input into a Person object at the client,
send it in the request to the service asynchronously, and expect the
resulting Person object on success.  Here’s how:

Assemble the Parameter

 

Let’s say we have a form on the page that allows the user to input a person’s name and age.  We then have a button, or link, that fires the asynchronous callback to save that data as a Person.  Here’s the javascript method to assemble the Person object and send it off to the MyService service SavePerson web method:

function SavePerson()
{
    //get the form data
    var name = document.getElementById(‘myNameElement’).value;
    var age = document.getElementById(‘myAgeElement’).value;       
    // new Person object, made available to us by the page’s
    // Atlas ScriptManager control
    var Person = new Person();   
   
    // populate the Person’s member values
    Person.Name = name;
    Person.Age = age;
   
    // Now, here’s where we make the callback to the
    // SavePerson web method   
    callbackSavePerson = new MyService.SavePerson(
        Person,
        {
            onMethodSuccess: SavePersonSuccess,
            onMethodError: SavePersonError,
            onMethodTimeout: SavePersonTimeout,
            timeoutInterval: 5000;
        }          
    );  
}

 

As you can see, we take the form input, create a new Person object and place the values from the form into the Person members Name and Age.  We then do is execute a callback to the SavePerson web method with a couple parameters: the first is our Person object that the web method is expecting as its only input parameter.  The second parameter is an array of callback handlers that every Atlas web method is given.  These handlers provide the actions to perform when the callback either returns or doesn’t return.  Notice that we can handle different failure reasons using seperate methods… allowing us to let the user know why the callback failed (the service threw an unhandled exception, or the callback didn’t return before the timeout interval).  Assuming the callback makes its roundtrip successfully, we’ll have a return result from the service, which will either be a new Person object, or a null value (as specified by our SavePerson web method).  Now we can write the various handlers: SavePersonSuccess, SavePersonError, and SavePersonTimeout.

Handle the Results

 

SavePersonSuccess(result) will have receive the result parameter – either a Person, or null.  So, we simply do a check:

function SavePersonSuccess(result)
{
    if(result != null) {
        alert(result.Name + ” was saved.”);
    }
    else {
        alert(“The service was unable to save the person.”)
    }
}

 

Remember that if the SavePerson web method returns a success, result will be an instance of the Person object – so we have access to its members: result.Name and result.Age. 

I’m not going to go too far into the  handling of the error or timeout conditions because there’s actually some more advanced things we can do there, and I’ll save that for another post.  In this example, though, we would simply write the specified handlers:

function SavePersonError(result) { alert(“The service encountered an error”); }
function SavePersonTimeout(result) { alert(“The service timed out.”); }

 

So there you have it, we created a web service MyService, with one web method SavePerson.  We called it, passed it a custom Person object, and got back a new instance of the Person object based on what was saved by the service – all asynchronously.  If you’re wondering how the client knew what a Person object was, and why we were able to create a new instance of it on the client-side… well that’s exactly the magic of Atlas and its ScriptManager control, which makes the necessary server-side classes available to us on the client-side.  And yes, it made the Person class available to us because it recognizes that the return type of our web method (SavePerson) was a Person.

For information on how the ScriptManager control works, visit http://atlas.asp.net

Related Posts

Tags

Share This

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>