2007
11.18

Continuation of Part 1

AJAX sample code – calling from a .NET page with C#

Now the good stuff.  How do we implement AJAX in our .NET pages?  The answer is surprisingly and pleasantly simple, as it turns out, and is not actually particular to any one scripting language, be it C#, php, perl or whatever.

The secret to AJAX is the XMLHttpRequest object.  Unfortunately, it has not been implemented in a totally consistent manner across browsers (what else is new?), but as it turns out, the code branching logic needed to overcome this problem is not bad at all.  All we have to do is test for the existence of the appropriate object with an “if” statement and we are ready to roll.

For the purposes of this simple AJAX tutorial, when my .aspx page loads, I am going to request data from a mythical web service (could be Amazon, Ebay, or any number of others), and present it in an asynchronous manner to the user when it comes in.  If the service is slow or if I am querying many web services in this page, the user will not be left waiting for them all to come back with a response.  The data will show up as it comes in.

Pieces to the puzzle

The first thing we need is a JavaScript function to call on some kind of event.  I have chosen an “onload” event for the page, but it could be on a button click, edit box “blur,” image load or whatever.  For the example here, all we need to do is put the following in our HTML page body tag:

<body onload=”AsyncDataRequest(1)”>

When the page loads, the browser will make sure that AsyncDataRequest gets called with a parameter of 1.  For the following functions, make sure all the code is in a <script language=”JavaScript”> </script> tag in the <head> section of your .aspx page.  Also, put a <span id=”ProductInfo1″>  </span> in your page where you want the response data to go.

The data request function simply looks at the page parameter passed in (optional), formats a request url and calls the function that actually makes the Http Request:

function AsyncDataRequest (page)
{
    var varProduct;
    var prodSpan;
    if (1 == page)
    {
        prodSpan = 'ProductInfo1';
        varProduct = 'Product1';
    }
    url = 'http://www.mysite.com/DataRequest.aspx?Query=' + varProduct;
    loadXMLDoc (url, processRequest, prodSpan);
}

We pass in a “page” parameter so we can more easily branch our logic based on what object is making the request.  Here, for page “1” we specify the name of a <span> tag (“ProductInfo1”) that will be filled in with our data later on and a product tag (“Product1”) that lets us return more specific information from our query.

We simply formulate the URL with the desired parameters and call another JavaScript function “loadXMLDoc.”  That function looks like this:

function loadXMLDoc (url, rsFunc, prodSpan)
{
    var reqHTTP;
    if (window.XMLHttpRequest)
    {
        reqHTTP = new XMLHttpRequest();
        reqHTTP.onreadystatechange = function()
        {
            rsFunc(reqHTTP, prodSpan);
        };

    reqHTTP.open("GET", url, true);
    reqHTTP.send(null);
    }
   else if (window.ActiveXObject)
   {
        reqHTTP = new ActiveXObject("Microsoft.XMLHTTP");
        if (reqHTTP)
        {
            reqHTTP.onreadystatechange = function()
            {
                rsFunc(reqHTTP, prodSpan);
            };

        reqHTTP.Open("GET", url, true);
        reqHTTP.send();
        }
    }
}

This function tests for the existence of the XMLHttpRequest object and makes our asynchronous request for data.
Notice how we have to branch our XMLHttpRequest creation with the if/else if so both IE and Firefox are happy.  With Firefox, XMLHttpRequest is a built-in object, but with IE, it is an ActiveXObject.  Such is life;  just accept it and go on.

The interesting thing here is the assigning of the “onreadystatechange” event of the request object to the function we want to be called when the event fires.  In case you haven’t seen it before, the onreadystatechange = function () syntax allows us to define what is known in JavaScript as an “anonymous function.”   The cool thing is that we can pass parameters to our callback function, and the script code will take care of preserving those parameters for the callback, even though it occurs later.

Note that “rsFunc” is the parameter we passed in to loadXMLDoc, which we called “processRequest.”  That is the function that will be called when the onreadystatechange event of the request fires (basically just when the request gets more data or an error condition).  More on that in a second.

The only things left to do here are call “Open” with the URL and “send.”

What does “processRequest” look like? I was hoping you would ask:

function processRequest(reqHTTP, prodSpan)
{
    if (reqHTTP.readyState == 4)
    {
        if (reqHTTP.status == 200)
        {
            response = reqHTTP.responseText;
            document.getElementById(prodSpan).innerHTML = response;
        }
    }
}

This is simple, boiler-plate code that looks for hardcoded numbers in the response. The readyState of the request has to
be 4 and the status has to be 200. Don’t worry about it, just accept it. Only under those conditions will the request give you good data.
Notice that we passed the request object that we created in loadXMLDoc to this function along with the <span> id originally specified in AsyncDataRequest.
Here, we get the response text from the request object, get the element of the document specified by id (prodSpan) and set its innerHTML to the response text. Voila. The text magically appears in the browser in the place where the <span> tag is.  Very cool.

Last piece to the puzzle — data!

So what does the code in DataRequest.aspx look like?  That’s mostly up to you.  That file does the dirty work of retrieving data from a database, 3rd party web service, validating user input against business rules, etc., etc.  Here’s a sample of what it might look like:

      String strQueryString = Request.QueryString["Query"];
      switch (strQueryString)
      {
        case "Product1":
            Response.Write(MyObject.GetAmazonData("Books");
            break;

        //Other product feeds responses here

        default:
            break;
      }

Here we are just branching our logic based on the Request string sent in the URL we formatted in the AsyncDataRequest function. Feel free to substitute whatever Request QueryStrings suit your needs.
In the GetAmazonData function you would request your data from the appropriate web service, format it (HTML would be desired here) and write it to the Response stream. Every thing else is automatic. Awesome.  You have to supply the logic in MyObject, however. :)

It’s OK for the GetAmazonData function to block for as long as it needs to, because the user is no longer waiting for the page to load.  This is the sweet part.   Here you could also do secret calculations or password validation, etc.

If you have done everything correctly, whatever HTML you put in Response.Write will show up in the ProductInfo1 <span> tag.

This should be a complete example that you can slice and dice to fit your own needs. If not, please post and let me know. Also, if you have found this helpful, please post your experience for others to read.
As you can see, this could easily be adapted to use in a php environment. The only thing that would be different is the trivial differences in syntax for the DataRequest page.

As an example, this link leads to a games site that has implemented Amazon Web Services as a monetizing tool to present games for sale:
Time Killing Games

Enjoy

midniteblogger

2007
11.16

AJAX, (which stands for “Asynchronous JavaScript and XML”) is a really cool technology.  Although not a perfect solution, AJAX has solved some difficult problems related to creating a “rich” user experience in a web browser.

With a traditional web page, the browser makes an http request to the server.  The web server delivers the HTML content to the browser and the connection between the browser and the server is then broken.  If the user performs some action on the page (e.g. fills out a form), the browser has to do another full round trip to the server, resulting in a page refresh, in order to get any information back to do something as simple as data validation.   This is a somewhat less than satisfying experience for the user, especially if the connection is slow.

Enter AJAX.

In this posting, I intend to cover the following subjects relating to AJAX:

-What AJAX is
-Reasons you would use AJAX
-Sample AJAX code that you can use on a .NET (.aspx) web page

A brief perspective

When I was first introduced to dynamic web page creation some time ago, I was very excited about the possibilities.  No more static .html pages and no more stale content.  Through the magic of the .php or .NET server pages, I could now introduce logic, database query results, 3rd party content and many other things on my sites.  This immediately led me to try integrating web service content from such vendors as Amazon in an effort to monetize my traffic.

While the integration was successful, the results of doing so were less satisfying — especially when querying more than one remote web service from a single web page at a time.  If there was any latency in one of the query connections, the whole page would block until all of the data was returned.  From a user’s perspective, this often meant that they could be left staring at a blank web browser (especially noticable under IE) for as much as 20 seconds — just waiting for the multiple query results to come back.

How AJAX can help

What is AJAX?

As mentioned above, AJAX stands for “Asynchronous JavaScript and XML.”  This means that it is JavaScript, executed in the browser, called in a manner that returns asynchronous results, frequently formatted as XML.  Most modern browsers (IE, Firefox, Safari, Opera) support JavaScript, so it should be a seamless experience for your site users.

The bad thing about using traditional JavaScript is that all your business logic is delivered to the client browser.  This makes it hard to manipulate any kind of passwords or trade secrets such as formulas with it.  The cool thing about what AJAX adds, is that it lets you keep all your business logic, password validation, secret calculations, etc. where they belong — on the server.

Reasons you would use AJAX

Here are a few reasons for using AJAX on your web pages:

-You want to integrate more than one 3rd party data source from typical Web service suppliers and want to avoid the multiple connection latency problem.
-You want to do some kind of data validation of user input (e.g. filling out a registration form) without either delivering all the logic to the client in JavaScript or making a round trip to the server with the resulting full page refresh.
-You want your web application to have the more natural feel and responsiveness of a traditional GUI desktop application.

More in Part 2