10 August 2005

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.

Keep up to date with Simple-Talk

For more articles like this delivered fortnightly, sign up to the Simple-Talk newsletter

Downloads

This post has been viewed 116537 times – thanks for reading.

Tags: , , , , ,

  • Rate
    [Total: 90    Average: 3.1/5]
  • Share

Paul Glavich (glav@theglavs.com) is an ASP.NET MVP who works as a Principal Consultant at Readify (http://readify.net/) in Australia. He has more than 22 years of industry experience, and was technical architect for one of the world’s first Internet banking solutions using .NET technology. His technical articles can also be seen on community sites such as ASPAlliance.com (www.aspalliance.com/).

View all articles by Paul Glavich

  • Anonymous

    I tried the example
    the example works, however, is’s not really async, since client has to wait for the server callback, the client can’t move to other places.

  • Anonymous

    Files for download
    The downloadable example files does not work.
    I get several errors when compiling:

    1. “onclick” on drop down
    2. _Default does not implement GetCallbackresult

    etc.

  • Anonymous

    example not work properly
    i try the example but not work properly, you are not implement ICallbackEventHandler correctly

  • Anonymous

    Example Code Doesn’t Compile
    Thanks for the waist of my time, your example download does not compile.

  • Anonymous

    Not working
    thankx for irritating the user your code does not work

  • Anonymous

    I tried the example
    you are not implement ICallbackEventHandler correctly..Apart from this code works very good.

  • Anonymous

    I triend the example
    it work but after submit button click it gives
    error of Invalid Callback or Postback argument

  • Anonymous

    Program is not running
    It gives an error.
    I.e.

    ‘_Default’ does not implement interface member ‘System.Web.UI.ICallbackEventHandler.RaiseCallbackEvent(string)’. ‘_Default.RaiseCallbackEvent(string)’ is either static, not public, or has the wrong return type.

  • Anonymous

    Code does not work
    Your code does not work. Have you looked at any of the previous comments?

  • Anonymous

    Not working
    Did u ever tried running the program what u have given ?

  • Anonymous

    try code before testing
    the concept maybe good but the example code does not work.

  • Anonymous

    HI
    it is very good but i could no understand it

  • Anonymous

    ICallbackEventHandler Implementation
    The implementation of the ICallBackEvenHandler changed from its original design in beta. Now we have:

    void ICallbackEventHandler.RaiseCallbackEvent(string eventArgument)
    {}

    and

    string ICallbackEventHandler.GetCallbackResult()
    {}

    All you need to do is declare a string variable in with Page scope, load its value in the RaiseCallbackEvent and reuse it at GetCallbackResult.

    Made short:
    public partial class blah: Page, IcallBackEventHandler
    {

  • Anonymous

    It didint fit:
    public partial class blah: Page, IcallBackEventHandler
    {
    string _eventArgument = “”;

    }
    void ICallbackEventHandler.RaiseCallbackEvent(string eventArgument)
    {
    this._eventArgument = eventArgument;
    }
    string ICallbackEventHandler.GetCallbackResult()
    {
    return “nPassed event argument: ” + this.eventArgument;
    }

    }

    and this will send the return of getCallbackResult() to the client script.

    I hope it helps.

    Fabio

  • Tony Davis

    Please sign in to comment

    Anonymous comments have been disabled on this article due to relentless spamming.

    Please do continue to comment — but you will need to sign in or join in order to do so. It jsut requires a username, email address and password. Simple-talk does not share user details with any third parties, under any circumstances.

    Best,

    Tony (ed.)