A Recipe for AJAX Webservices

This is a fun and useful concept that is actually really very easy to implement. The recipe calls for two cups webservice, an ounce of AJAX ScriptManager, finished with a dash of javascript.

Note: Begin with an AJAX Enabled Website!

Let’s Start With the Webservice

Obviously, to work with AJAX Webservices you need to start with a webservice. You can use any webservice that you like depending on the application; for the purpose of this demonstration our objective will be to retrieve a list of employees and their job application (sort of).

Instead of working with SQL to retrieve the data, I am going to simulate this process and then write everything into XML format to make it easier to work with in javascript. Under normal conditions, I would be retrieving information from a database, otherwise the webservice would be a bit pointless.

Below is the pseudo-code to setup our mock webservice:

<WebMethod()> _
    Public Function getData() As String
        Dim dt As New DataTable
        Dim dr As DataRow
        Dim dc As DataColumn

        dc = New DataColumn
        dc.ColumnName = "Name"
        dc.DataType = GetType(String)
        dt.Columns.Add(dc)

        dc = New DataColumn
        dc.ColumnName = "Occupation"
        dc.DataType = GetType(String)
        dt.Columns.Add(dc)

        dr = dt.NewRow()
        dr("Name") = "Nicholas B"
        dr("Occupation") = "Computer Geek"
        dt.Rows.Add(dr)

        dr = dt.NewRow()
        dr("Name") = "Logan B"
        dr("Occupation") = "Jon-boat Captain"
        dt.Rows.Add(dr)

        dr = dt.NewRow()
        dr("Name") = "Ben G"
        dr("Occupation") = "Aspiring Computer Geek"
        dt.Rows.Add(dr)

        dr = dt.NewRow()
        dr("Name") = "David M"
        dr("Occupation") = "Pool Shark"
        dt.Rows.Add(dr)

        dr = dt.NewRow()
        dr("Name") = "Eric V"
        dr("Occupation") = "Inventory Terminator"
        dt.Rows.Add(dr)

        Return getDataXML(dt)
    End Function
    
    Public Function getDataXML(ByVal dt As DataTable) As String
        Try
            If dt.Rows.Count > 0 Then
                Dim sb As New StringBuilder
                sb.Append("<?xml version=""1.0"" encoding=""iso-8859-1""?>")
                sb.Append("<crew>")

                Dim array(dt.Rows.Count - 1) As Double
                For i As Integer = 0 To dt.Rows.Count - 1
                    sb.Append("<person>")
                    sb.Append("<name>" & dt.Rows(i).Item("Name") & "</name>")
                    sb.Append("<occupation>" & dt.Rows(i).Item("Occupation") & "</occupation>")
                    sb.Append("</person>")
                Next

                sb.Append("</crew>")

                Return sb.ToString()
            Else
                Return Nothing
            End If
        Catch ex As Exception
            Return Nothing
        End Try
    End Function

The getDataXML() function is just to help move the datatable format into XML in the schema that I want for this demo. The key here is that you have a webservice and it is doing something (in this case returning a list of employees in XML format).

A Secret Ingredient

There is one last secret ingredient that needs to go into your webservice. You need the following line above your webservice class declaration:

<System.Web.Script.Services.ScriptService()> _

This line enables the webservice to be called from javascript and is required.

A Bit of AJAX Script Manager

Next we need to register the script manager and script manager proxy. Take a look at the following code, which goes in the HTML:

<asp:ScriptManager ID="ScriptManager1" runat="server" />
    
    <asp:ScriptManagerProxy id="ScriptManagerProxy1" runat="server">
    <Services>  
        <asp:ServiceReference Path="~/webservice_demo.asmx" />
    </Services>
    <Scripts>
        <asp:ScriptReference Path="~/javascript_demo.js" />
    </Scripts>
    </asp:ScriptManagerProxy>
    
    <input type="button" value="Get Data" onclick="getDataJS();" />

<div id=”crew”> </div>

“~/webservice_demo.asmx” is the location of my webservice file and ~/javascript_demo.js” is the location of my external javascript file (which we haven’t covered yet).

The input button is just going to be our trigger to execute the AJAX webservice call; this could be any event-based trigger. The div tag (crew) is just a container to hold our results when they are returned.

Our Dash of Javascript (Maybe a Bit More than a Dash)

//Get all locations from webservice getLocationInfoByUser()
function getDataJS() {
    var ret = webservice_demo.getData(getDataJS_Complete, onError, onTimeout);
    return true;
}

function getDataJS_Complete(arg) {
    // code for IE
    if (window.ActiveXObject) {
        var doc=new ActiveXObject("Microsoft.XMLDOM");
        doc.async="false";
        doc.loadXML(arg);
    }
    // code for Mozilla, Firefox, Opera, etc.
    else {
        var parser=new DOMParser();
        var doc=parser.parseFromString(arg,"text/xml");
    }
    
    // documentElement always represents the root node
    var x=doc.documentElement;
    
    var htmlstring = "";
    
    for(i=0;i<x.childNodes.length;i++) {
        var name = x.childNodes[i].childNodes[0].childNodes[0].nodeValue;
        var occupation = x.childNodes[i].childNodes[1].childNodes[0].nodeValue;
        
        htmlstring += "<p>" + name + " " + "(" + occupation + ")</p>";
    }
    
    document.getElementById("crew").innerHTML = htmlstring;
}

function onError(arg) {
    alert("Error");
}

function onTimeout(arg) {
    alert("Timeout");
}

Let’s walk through the javascript a bit. First, getDataJS() is being called from our button onclick event. It simply calls our proxy webservice. Notice, our webservice doesn’t have the additiona onComplete, onError, onTimeout parameters. These parameters were added by the proxy as all webservices being called through the AJAX Script Manager needs to account for errors, timeouts, and successes.

The next function, getDataJS_Complete() gets executed if a sucessful call to the webservice is made. The code that we added loops through the XML and builds a simple listing of the results returned. It then passes those results into a div we had on the page.

We’ve taken a pretty cheap way out of the error and timeout handling. You can get creative with what happens upon errors; this is pretty standard just to show there was a timeout or there was an error with the webservice.

Bon Apetit

So, without a whole lot of pain we’ve created an AJAX webservice that we can call in our webpages. Hope this helps!

2 thoughts on “A Recipe for AJAX Webservices

  1. Hey, I found this blog article while looking for help with fixing Microsoft Silverlight. I’ve recently switched internet browser from Safari to Firefox 3.2. After the change I seem to have a issue with loading websites that use Microsoft Silverlight. Everytime I go on a page that requires Microsoft Silverlight, my browser freezes and I get a “npctrl.dll” error. I can’t seem to find out how to fix the problem. Any aid getting Microsoft Silverlight to work is greatly appreciated! Thanks

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s