Asynchronous client script callbacks

This article provides an example of asynchronous client script callbacks in ASP.NET V2.0.

Call them what you will, there’s value in asynchronous client script callbacks

There has been a lot of interest in the web-facing community lately about a new useability feature that goes by a number of different names-XMLHTTP, AJAX, out-of-band requests, and asynchronous client script callbacks, to name a few.

Regardless of the name, this feature provides a way for a standard web page to make calls back to the server, without a traditional page refresh. The user is oblivious to the fact that a server call has occurred, and is not interrupted by it.

An example is best to illustrate this: You are navigating a web page and select a value from a drop-down list. In a typical scenario, your selection signals the web page to call the server, and you experience a delay while the page retrieves information and displays the results. You could not enter or select information until the server executed the call and returned a response to the browser.

Using asynchronous client script callbacks, the name we will use in this article, you select a value from a drop-down list and a server request is made in the background, so there is no delay. When the server call finishes executing in the background, the details are updated on your browser.

This technology is not new, but it requires browser support. Now that a majority of browsers are on board, users can take advantage of the functionality the technology provides.

Google is doing a trial of the technology to enhance its users’ web-searching experience. Results are loaded in the background while Google displays suggestions for users as they type. You can try it for yourself here.

Where does ASP.NET fit?

ASP.NET V1.0 and V1.1 have no explicit support for this technology. Although they provide basic ways to manipulate script blocks, there is no easy way to incorporate more advanced techniques such as asynchronous client script callbacks.

With the upcoming release of ASP.NET V2.0, however, Microsoft focused on useability. This is evident when implementing common tasks and more complex technologies. In fact, ASP.NET V2.0 contains out-of-the-box support for asynchronous client script callbacks and provides a fairly simple way to register the callback methods, invoke them, and handle any associated errors.

Show me the money

Let’s look at a simple example of asynchronous client script callbacks and how they are implemented within ASP.NET V2.0.

The code below shows a simple page with two drop-down lists. (Note: The code can be downloaded using the link at the top of the page.) One list causes a postback to occur that updates the text-description field. The other drop-down list uses asynchronous client script callbacks to perform the same task. The server-side code inserts a two-second delay to simulate the latency that is typically involved when executing a postback operation.

The two text fields at the bottom of the page serve no purpose other than to accept data input. When executing a postback, data can be typed into these fields, but once the postback is complete, the fields are cleared to their previous state. The two text fields can be edited once the client script callback operation is complete, with no loss of data. The text description field is updated with the computed description value. (Note: The code below represents one ASPX page and its associated code beside file.)

Demo 1: Default.aspx (page component)

Demo 1: Default.aspx.cs (server-side code beside component)

Making the magic

Now let’s look at what is required to make the asynchronous client script callback magic occur within ASP.NET 2.0.

The server-side component, which receives the client script callback event, must implement the ICallbackEventHandler interface. This interface has only one method:

This server-side method is called when the client-side asynchronous method is called. A string, typically the ASPX page, is returned to the caller.

A text description is returned and displayed in the text description field. In a typical page implementation, the ASPX page class must implement the ICallbackEventHandler interface as shown below:

Creating the asynchronous callback event

To invoke an asynchronous client script callback, we must first obtain a reference or entry point to the javascript that invokes the asynchronous method. We can then register the event reference in the ASPX page, so it can be called as required by the client-side script.

To do so, we use the GetCallbackEventReference method that is part of the ClientScriptManager class. All the client-side scripting functionality resides in the ClientScriptManager class, including the RegisterClientScriptBlock and RegisterStartupScript methods that existed in the V1 and V1.1 framework. The ClientScriptManager class is also a member of the System.Web.UI.Page class, so any methods of this class can be accessed as shown below:

This returns a block of javascript, or event reference, that can be used to trigger the asynchronous client-side callback. The returned javascript looks like this…

…because the client-side code has no knowledge of this event reference and the invocation method could change in a future version of the framework. So we need to wrap the client-side code in a well-defined, well-named javascript function that the client-side code knows about and for which it provides a well-known signature.

Compare the code below to the example at the beginning of this article:

We have obtained the event reference and registered a javascript function called DoTheCallback, which invokes the asynchronous client-side event.

The javascript function takes two parameters, arg and ctx. These arguments obtain the callback event reference. You could use any parameter name, and the returned callback event reference-the javascript block-specifies the use of the parameters as argument/variable names within the client-side callback method to initiate the callback.

It’s important to remember that the parameters arg and ctx must be used as part of the client-side callback function.

Calling/invoking the asynchronous callback event

We have now created the plumbing required to implement the asynchronous client script call on the client. To initiate the process, the client, or browser, makes a call to the DoTheCallback function that was registered in the server-side code above.

This function accepts two parameters: arg, for passing function arguments to the server-side method; and ctx, which is contextual information that will be passed to the client-side callback when the server-side method has executed. (Note: It is not available to the server-side method.) It is useful to indicate in the client-side callback method the context or mode in which the callback might be operating.

The function to invoke the asynchronous client call is a standard javascript call, so it can be made from anywhere within the browser where javascript can be used.

Displaying/processing callback event results

The javascript call in the browser has initiated an asynchronous client-side call that calls the RaiseCallbackEvent method on the server. This method performs some server-side processing, typically using what was passed in from the asynchronous client-side call as input via the arg parameter, and returns a string.

Execution of the asynchronous client-side call can take two paths. If no error occurs in execution on the server via the RaiseCallbackEvent method, client-side execution continues to the javascript function registered in the server-side code in the Page_Load method using this statement:

In this example, it is the ClientCallbackFunction function:

The string value returned from the RaiseCallbackEvent method on the server is passed in via the arg parameter, and the ctx parameter contains contextual information specified via the DoTheCallback method that initiated the asynchronous call-in this example ‘0’. DHTML is used to update the browser display with the text returned from the server.

If an exception in processing occurs on the server and an error callback is registered, the javascript function is called passing in the error details. This is not shown in this example, but to take advantage of this functionality, you alter the initial call to GetCallbackEventReference to add an additional client-side function to register as shown below:

We have registered an additional javascript function, ClientCallbackErrorFunction, to act as the recipient client-side method in the event of an error.

On the client, or browser, we simply provide a javascript method such as:

Any exception that occurs on the server side will generate a call to this function, passing in error details via the err parameter.

It’s not all a pretty picture

Asynchronous client script callbacks are a powerful feature, but they can be limiting. You can only pass a string to the server-side method, for example, and only return a string. This simplistic data exchange can be a source of frustration when more complex data exchange is required.

In addition, multiple controls on a page require asynchronous processing methods. So for asynchronous processing of multiple elements, you must look at custom ways to split the string into multiple elements to serve the requirements of the page.

Although the ASP.NET V2.0 implementation falls short in flexibility, it is provided out of the box, which means many developers will use it by default. Microsoft is now looking at ways to enhance the functionality of the feature.

In contrast, AJAX.NET provides a robust, full-featured implementation for V1.0 and V1.1 of the .NET framework. The free library supports a number of data types within .NET and uses an attribute-based mechanism for multiple asynchronous method support. (See http://ajax.schwarz-interactive.de/csharpsample/default.aspx for the AJAX implementation.)

Conclusion

This article provides an example of asynchronous client script callbacks in ASP.NET V2.0. It has shown the concept and implementation of the technology, but it can be taken further. The GridView control in ASP.NET V2.0 supports asynchronous client script callbacks by default for features such as data paging. This shift in functionality from previous versions of similar controls will be a boon to useability.

Developers don’t need to know anything about the asynchronous client script callback feature to take advantage of it. The technology is moving into mainstream development, which will shape how it is implemented in the future. The details may differ, but the use of asynchronous client-side callbacks-or whatever name you choose to call them-will play a part in many future projects.