Problems when using Client Callbacks in ASP.NET 2.0

Note: This entry is an introduction to one of the new problems/features that occur in the RC1 and RTM versions of ASP.NET 2.0. In this particular posting I’ll cover the basics of client callbacks. In a next posting I will address the RegisterForEventValidation method and enableEventValidation attribute of the page element in the web.config.

ASP.NET 2.0 introduces Client Callbacks, allowing you to make callbacks to the webserver from the web page without leaving it. You do make a roundtrip to the webserver, but it is performed behind the scenes. The browser never shows any signs of the roundtrip by spinning the globe (if you use IE, that is). The roundtrip is not a postback.

The callback is performed by using the MsXml2.XmlHttp COM object which sends strings back and forth between browser and server. The ASP.NET runtime uses an infrastructure to facilitate in starting the asynchronous callbacks and handling the returning response from the server. Surely you have heard of Asynchronous JavaScript and XML (aka AJAX), which is sort of what we are talking about here.

When the response returns from the server, it usually brings some data that can be used to update the user interface using Dynamic HTML. Take a look at Google Suggest and http://www.start.com to see the ways how you can achieve a responsive user interface and smooth experience with this mechanism.

To give you an idea how this all works, let me walk you through the steps of the Client Callbacks from ASP.NET 2.0:

  1. a client-side event triggers the start of the callback.
  2. the event-handler of the event will use a method call to the client callback manager that sends an asynchronous request.
  3. the call arrives at the same webpage that constructed the page. This page must implement the ICallbackEventHandler interface.
  4. the server sends back the response to the client.
  5. the client callback manager handles the response and calls the callback function (kinda confusing maybe, but this one is at the client). Typically this function will update the user interface.

Let’s make an little demo. Take the following two controls: a dropdown and a listbox.

<asp:DropDownListID=”DropDownList1″Runat=”server”>
  <asp:ListItemText=”Item 1″
/>
  <asp:ListItemText=”Item 2″
/>
  <asp:ListItemText=”Item 3″
/>
</asp:DropDownList>
<asp:ListBoxID=”ListBox1″AutoPostBack=”true”Runat=”Server”/>

The idea is to make a callback to the server as soon as the user selects an item from the dropdown. The server should return related items to the client, which get displayed in the listbox.

For step 1 we will use the onChange client-side event of the dropdown control. The call from step 2 to the client callback manager that will start all of this UI goodness can be constructed with some server-side code:

string callBack = Page.ClientScript.GetCallbackEventReference(this, “arg”, “ClientCallback”, “context”, “ClientCallbackError”, false);
string clientFunction = “function GetChildren(arg, context){ “ + callBack + “; }”
;
Page.ClientScript.RegisterClientScriptBlock(
this.GetType(), “GetChildren”, clientFunction, true
);
DropDownList1.Attributes.Add(
“onChange”, “GetChildren(this.options[this.selectedIndex].value, ‘ddl’);”);

This piece of code will create a client-side JavaScript block with a method called GetChildren. It contains the call to the callback manager, that is constructed by GetCallbackEventReference. Finally, GetChildren is hooked up to the onChange event.

The arguments “ClientCallback” and “ClientCallbackError” in GetCallbackEventReference refer to two methods that should exist in client-side JavaScript as well. The first will handle the callback at the client if a succesful roundtrip was performed, the other any failures. Here’s what they look like:

function ClientCallback(result, context) {
  var listBox = document.forms[0].elements[‘<%= ListBox1.UniqueID %>’
];
  if (!listBox) { return
; }
  listBox.length = 0;
  if (!result) { return
; }
  var rows = result.split(‘|’
);
  for (var
i = 0; i < rows.length; ++i) {
    var option = document.createElement(“OPTION”
);
    option.value = rows[i];
    option.innerHTML = rows[i];
    listBox.appendChild(option);
  }
}

function ClientCallbackError(result, context) {
  alert(result);
}

Never mind the DHTML stuff. It just updates the UI. That takes care of step 5. The callback manager is included into the page by a JavaScript block with a reference to an embedded web resource with the URL: WebResource.axd?d=MwVD6rEVTks4d5ShlKs6gA2&t=632643142164565472. (BTW, this file also contains a FireFox compatible MaintainScrollPosition (aka SmartNavigation) implementation.)

Last thing to do is an implementation of the ICallbackEventHandler interface in the web page. That should look something like this:

publicpartialclassClientCallbacks: System.Web.UI.Page, ICallbackEventHandler
{
  // … Some stuff omited
 
private
string eventArgument;

voidICallbackEventHandler.RaiseCallbackEvent(string eventArgument) {
  this
.eventArgument = eventArgument;
}

stringICallbackEventHandler.GetCallbackResult() {
  switch
(eventArgument) {
    case“Item 1”
:
      return“One|Two|Three”
;
    case“Item 2”
:
      return“Four|Five|Six”
;
    case“Item 3”
:
      return“Seven|Eight|Nine”
;
    default
:
      return“”
;
  }
}
}

The interface has changed from beta 2. It returns a delimited list of related items for the argument that arrives at the server. The way you format your data is entirely up to you. Of course, you will have to set up the client-side callback script to work with this format as well.

To give it all a spin you can download the sample files:
clientcallback.aspx
clientcallback.aspx.cs

Try selecting items from the dropdownlist. Items should appear in the listbox. It should all be working fine, up until the point where you select an item from the listbox and cause an actual postback to the server. Then it all blows up. That’s the bit that I actually wanted to talk about. It will be stuff for the next entry. I’ll amuse (or irritate) you with the error page, so you know what should be going wrong.

Soon you will now why you get this error and how you fix it, plus some other nice client callback things you should know about.

Advertisements
This entry was posted in Uncategorized. Bookmark the permalink.

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