Fun with callbacks Part 1: What's in the ASP.NET box?
There's a lot of buzz currently around Web out-of-band calls, aka XmlHttp, aka AJAX (the guy who coined this term must be some kind of marketing genius for imposing a new acronym for a technique that's been used for many years). It seems like the world is suddenly discovering that it is possible to get an update to a Web page from the server without posting back. Many techniques have been used for that purpose: Java applets (ASP classic was using this technique in Remote Scripting more than eight years ago), hidden frames and iframes, dynamically reloaded <script> elements and even reloading transparent images using cookies as the information transportation vessel. But the technique really became more than just a clever hack when Microsoft introduced the XmlHttpRequest object in Internet Explorer 5. The goal was to populate Xml data islands without sending back the whole page, hence the Xml prefix, but today it doesn't have much to do with Xml any more as the data that's transferred is most of the time not Xml. Client-side Xml never really happened.
Of course, the main reason why all this buzz is happening now is that Google is using the technique extensively in almost all of its recent betas (Google Maps, Google Suggest, GMail, etc.). If your e-mail is using an Exchange server, you probably also know Outlook Web Access, which is the most amazing Web application I've ever seen. It feels almost like the desktop version, it has context menus, drag & drop, multiple selection using CTRL+Click, rich text editing, etc. And of course, the MSDN library TreeView has been expanding nodes out-of-band for as far as I can remember.
So, what do we do in ASP.NET 2.0 to make it as easy as possible to develop Web applications that take advantage of this technique? A lot, actually. First, some of the new controls just use the technique out of the box. TreeView populates nodes on-demand without posting back, GridView paginates without posting back, etc. Second, there is an API for control developers that makes it very simple to add the feature to your controls without having to worry about most of the plumbing. You end-up basically handling control events as usual.
You just need to write the client-side script that will prepare the event arguments, the server-side event handler that will handle these arguments and return a response, and the client-side script that will take the response and reinject it into the page.
Here's a very simple and silly example:
<%@ Page Language="C#" Title="Fun with callbacks: a simple one" %>
<%@ Implements Interface=System.Web.UI.ICallbackEventHandler %>
<script runat=server>
string ICallbackEventHandler.RaiseCallbackEvent(string eventArgument) {
return "Hello, " +
eventArgument +
". Your name is " +
eventArgument.Length.ToString() +
" characters long.";
}
</script>
<html>
<head runat=server/>
<script>
function OnCallback(result, context) {
alert(result);
}
</script>
<body>
<form runat=server>
Enter your name here:
<input name="name" />
<input type=button ID=CallbackBtn value="Send"
onclick="<%= ClientScript.GetCallbackEventReference(
this,
"document.forms[0].name.value",
"OnCallback",
"this",
"OnCallback",
true) %>" />
</form>
</body>
</html>
Here, the client-side script is very simple. We get the callback script we need by calling the ClientScript API, using the page (this) as the event target, the contents of the input box as the event argument, and OnCallback as the client-side function to call with the results.
The server-side script is just an event handler for the callback event where we take the argument string and do some calculations on it before we return the result string.
And that's all, we don't need to write any more code. But we can do even better. I've noticed that many callback scenarios are just refreshing some part of the page. So to avoid having to write the client-side script that takes the results from the server and reinjects them into the DOM, I've written a small WebControl that handles that for you. It's called RefreshPanel and I'll show how to use it in the next post in this series.
In the meantime, you can find its source code as well as a few sample user controls that use it at this address:
http://www.gotdotnet.com/workspaces/workspace.aspx?id=cb2543cb-12ec-4ea1-883f-757ff2de19e8
Read on to the second part:
http://weblogs.asp.net/bleroy/archive/2005/04/15/400792.aspx
The third part:
http://weblogs.asp.net/bleroy/archive/2005/05/19/407539.aspx
And the fourth:
http://weblogs.asp.net/bleroy/archive/2005/06/27/415936.aspx