Home > View Post

Ajaxed Part I. Client side AJAX

In the introduction to this short series I mentioned that we'd be looking at the two flavours of AJAX supported in the ASP.NET AJAX Extensions. Today we'll look at client-side AJAX.

In a client-side AJAX approach the code that presents the data from an out-of-band (asynchronous) AJAX call mostly resides on the client as JavaScript. In this scenario the server is only responsible for sending data to the client. Traditionally in XML format, the data would be parsed by the some JavaScript on the client and the Browser DOM updated dynamically to include the new data.

In order to make the scripting on the client easier, more and more AJAX implementations have turned to JSON (JavaScript Object Notation) as their wire format instead of XML.

JSON

JSON is a neat notation to describe JavaScript objects that is, conceptually at least, similar to XML. There are two advantages of JSON over XML: JSON is a less verbose notation and therefore consumes less bandwidth (personally, I think this is mostly negligible but that's an argument for another day) but the big win is how easily JSON can be deserialized into JavaScript objects. Because JSON is JavaScript, deserialization is just a question of evaluating the JSON string. Easy peasy.

Take this XML 'object' (you can imagine how it would deserialize into a POCO) ...

<Person>
    <Name>Nobby Stiles</Name>
    <Age>34</Age>
    <PhoneNumber>555-1234</PhoneNumber>
</Person>

... and the JSON equivalent:

{ "Name" : "Nobby Stiles",
"Age" : 34,
"PhoneNumber" : "555-1234" };

JSON is the format of choice for the ASP.NET AJAX Extensions.

Web Services

The extensions have been engineered to work with ASMX Web Services - the idea being that you can call a Web Service directly from JavaScript code running on the client with two notable caveats:
  • The Web Service must be at the same domain
    This is a restriction of the XmlHttpRequest which, for security reasons, cannot make calls to other domains. The workaround for this is to wrap any remote web services with a local asmx web service.
  • The Web Service must be marked [ScriptService]
    (and be running on a server with the extensions installed). This is a notable exception because it means that any existing web services (on the same domain) would require a (fairly trivial) change. Of course, such web services could also be wrapped with a local asmx that implements [ScriptService].

An example

For the purposes of our demonstration, we'll use the following very simple WebMethod in our web service.

[WebService(Namespace = "urn:schemas-thejoyofcode-com:ajaxed:people-service:2007-01")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[ToolboxItem(false)]
[SoapDocumentService(ParameterStyle=SoapParameterStyle.Bare)]
[ScriptService]
public class PeopleService : System.Web.Services.WebService
{
    [WebMethod]
    public List<Person> GetPeople()
    {
        return PersonDB.GetAllPeople();
    }
}

So that's just a method to return a list of people (remember the people shape above?). The important thing to note is the addition of a ScriptService attribute to the web service.

Now we need a web page to play with some AJAX calls to our web service.

The AJAX test page layout

We have a button "Get People" and a listbox (select element with the size attribute set to 10).

<form id="form1" runat="server">
    <asp:ScriptManager ID="_theScriptManager" runat="server">
        <Services>
            <asp:ServiceReference Path="PeopleService.asmx" />
        </Services>
    </asp:ScriptManager>
    <button id="_btnGetPeople" onclick="fetchPeople()">Get People</button>
    <br />
    <div>
        <select size="10" id="_lstPeople" />
    </div>
    <br />
    <a href="ServerSide.aspx">Server Side</a>
</form>

We want the "Get People" button to make an out-of-band AJAX call to the People service and use the results to populate the listbox.

You probably noticed that the "Get People" button fires a JavaScript method in its onclick handler. Remember, this is client side AJAX so we're going to have to get our hands dirty. Our handcrafted fetchPeople method, that resides in a script block at the top of the page, looks like this:

function fetchPeople()
{
    Ajaxed.PeopleService.GetPeople(fetchPeopleCallback);
}

So where does this "Ajaxed" namespace and "PeopleService" object come from? Hopefully, you noticed the ScriptManager element in the aspx markup above and that it adds a 'ServiceReference' pointing to PeopleService.asmx that we created earlier. Well that's where it comes from and that's how we can call the service directly from script.

You may have noticed that I do nothing with the return of the function and the parameter I pass is called fetchPeopleCallback. That's because AJAX is asynchronous and most implementations use a callback to handle the response - same here. The fetchPeopleCallback is a pointer to another JavaScript method.

function fetchPeopleCallback(results)
{
    var lstElm = document.getElementById("_lstPeople");

    lstElm.innerHTML = ""; // very crude way of clearing the listbox.
    
    for (var i=0; i &lt; results.length; i++)
    {
        var opt = document.createElement("option");
        opt.text = results[i].Name + ", " + results[i].Age + ", " + results[i].PhoneNumber;
        opt.value = opt.text;
        lstElm.options.add(opt);
    }
}

And there we have it. The response from the WebService calls this method which takes the data and adds it to our listbox. Doddle.

What I think is most interesting about this is how the results object has the appropriate shape. That is, it's an array containing multiple Person objects with their Name, Age and PhoneNumber properties. Very very cool.

All too easy...

So that was pretty easy, right? Why do we need another 'Server-Side' approach?

All we've looked at so far is a very simple scenario. Let's imagine you want to render data in a more complex way, like a GridView or something. No help from ASP.NET here, you'll be working up that presentation all by yourself. Want to have another button that causes a normal postback to the server? You'll be landing yourself in the tricky world of managing your own state (the viewstate knows nothing of what you've been doing to the page out-of-band). It can all get complicated terrifically quickly but it is, at the same time, terrifically powerful. There's much more on offer than shown here too - this is just an introduction.

Next, we'll look at the Server Side approach to AJAX supported in the ASP.NET AJAX extensions. In the meantime, why not download the code from todays example.

UPDATE: The second part Ajaxed Part II. Server Side AJAX is now available.

UPDATE: The AJAX Extensions have gone RTW (Release To Web) - find out more here.

Tags: ASP.NET

 
Josh Post By Josh Twist
6:07 AM
19 Jan 2007

» Next Post: Ajaxed Part II. Server Side AJAX
« Previous Post: An introduction to the ASP.NET AJAX Extensions

Comments are closed for this post.

© 2005 - 2017 Josh Twist - All Rights Reserved.