Tales from the Evil Empire

Bertrand Le Roy's blog

News


Bertrand Le Roy


Add to Technorati Favorites Tales from the Evil Empire - Blogged

Blogs I read

My other stuff

Archives

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

Comments

Ron A. Buckton said:

I was working on a project for DDI (www.ddiworld.com) back in 2002 when .NET 1.0 was released. The project used OOB/XmlHttp stuff from the getgo, and MS even did a case study way back when (http://www.chroniclesdesign.com/ddi.pdf).

Prior to that I was using XML-RPC way back before SOAP in my ASP days, yet more XmlHttp. Its definately nothing new, but until recently there's never really been much of a "framework" for OOB support. (Excepting webservice.htc, which was still only a small piece of the puzzle).

New features like client-callbacks should make this easier in .NET 2.0 (and even 1.x, I have some sample code in a SIG presentation I did (http://www.bennettadelson.com/downloads/NetSigSolution2-8-05.zip) and will have an article on it in a couple days on my blog), building in a lot of support directly into .NET.
# April 8, 2005 11:39 PM

JosephCooney said:

I think the WebService DHTML behavior (on the client) and ASMX on the server is much better than ASP.NET's async callbacks....so much so that I wrote this sample comparing the two.

http://www.gotdotnet.com/Community/UserSamples/Details.aspx?SampleGuid=fd6acac1-da45-446c-822d-5b2ecdb396a6

and this critique of it

http://jcooney.net/archive/2004/02/26/343.aspx
# April 9, 2005 4:25 AM

TrackBack said:

# April 9, 2005 4:39 PM

TrackBack said:

Best of the Blogs - Ian Smith reviews the best of the last week's web development blogs so that you don't have to. Week ending 10th April 2005. Whidby, Visual Studio Team System, Visual Studio 2003, Training, Productivity Enhancers, Front-End Development and more...
# April 10, 2005 5:14 PM

TrackBack said:

Bertrand Le Roy, one of the rock-star developers on the Web Platform and Tools team has been doing a...
# April 10, 2005 7:51 PM

Uwe Keim said:

Great! I already played with this, too. Seems that this ASP.NET 2.0 Callback stuff also seems to be aware of different browsers and works correctly on FireFox, too?!?
# April 11, 2005 12:30 AM

Bertrand Le Roy said:

Uwe, it depends which build you're using. The beta builds should play nicely with Firefox, and the final version will address more browsers, like Opera.
In any case, any control you develop with this technology should degrade gracefully to ordinary postbacks on older browsers. It's the case of some of my samples, but not all, for the sake of simplicity (they are sample, not production quality controls).
# April 11, 2005 12:43 AM

Bertrand Le Roy said:

Joseph: The callback feature IS aimed at control developers. You seem to forget a small detail about behaviors: they're only available on IE. The ASP.NET callback feature already works on IE and Firefox and the final version will work on more browsers.
The example about wiring up several text boxes can be solved by the CallbackMultiplexer sample control that's included in my sample workspace (http://www.gotdotnet.com/workspaces/workspace.aspx?id=cb2543cb-12ec-4ea1-883f-757ff2de19e8).
Another problem with the web service behavior when compared with the ASP.NET callbacks is that you need to create a web service for each control, whereas with callbacks, everything is integrated in the page and control lifecycle.
That's very important: with web services, there's no way you're going to be able to access other controls on the page and integrate them in your update procedure. With callbacks, your update procedure executes in the context of the page, so all controls are fully available.
# April 11, 2005 1:13 AM

Steven Livingstone said:

Belive it or not the last few days i have been working on moving some old Remote Scripting features of a huge system to use XMLHTTP.

The feature above sounds very interesting. I assume it works fine through firewalls and proxies!? (i ask as this is on reason we are moving from Remote Scripting which runs into trouble over our proxy when using an older Sun JVm on the client!).

They key is if you guys can get this to just work cross-browser. I like the idea and would be very intersted in how this ties in with ViewState and postbacks.
# April 12, 2005 3:55 AM

JosephCooney said:

I was less-than-impressed with the async callback feature since it did NOT work in firefox IIRR in the PDC release that I tested, but it is great news if it will work on more in the final release. For control developers I can honestly see the benefit, but if you went the web-service route instead of the ASP.NET async callback route you don't necessarily need 1 web service per control, you just need one webmethod per type of async operation you want to perform.

I don't really buy into the "can't access other controls on the page" argument. If your using web services and need the state of the controls to be sent back to the web service you can just do that from your callback code. Using ASP.NET async callback you can't change the properties of the control inside the callback anyway, becuase the viewstate has already been written to the client (unless some very impressive script has been added in the last little while to re-write the viewstate on the client once the call returns).

I love the async idea (especially the part about making it easy) - I just wish it could have been more strongly typed. The client-side script that the current DHTML behavior could have been rolled into a control, so the fact that it is currently in a DHTML behavior is more of an implementation issue IMO.
[cross-posted from my weblog, with some more junk as I thought it up]
# April 12, 2005 4:58 AM

Bertrand Le Roy said:

Steven: it works with proxies and firewalls. Callback requests look just like any other http request from the exact same client as far as the firewall is concerned. And it does work cross-browser (IE and Firefox are supported for the moment, more to come for RTM).

Joseph:
It didn't work with Firefox in the PDC build, but let's be honest, what did? The PDC build was an early alpha. Beta 2 should be available any time now.
If you're using callbacks, you can have the same reusability you have with web services by isolating the code in a separate method and just calling that from your event handlers. Actually, it is pretty obvious that this is the good practice if your callback logic is not specific to this control.
The only state you can use with the web service approach is the client-side state, not the server-side state. That means more client code, and nobody want that, right? With callbacks, you just have access to your other controls as usual, it just works. With web services, your client-side code has to take the client-side state (if it exists at all in a usable form: think about the state of a TreeView) and package it into XML for the web service to consume.
The real reason why the ViewState is not updated during callbacks is that the page lifecycle is not completely executed, and because several asynchronous callbacks can happen at the same time in the current build (which is not beta 2). Otherwise, it would be fairly easy to send the new value of the viewstate back to the client.
Anyway, I'm not talking about *changing* the state of other controls on the page, I'm talking about using it.
The point is that ASP.NET callbacks are fully integrated into the page lifecycle and web services are not. This has many advantages, another one being ease of writing.
I understand your point about strongly typing. The problem is that there is a huge impedance mismatch between the JavaScript type system and the SOAP and .NET type systems. If you go the strongly-typed way client-side, where do you stop?
I kind of like the frameworks that try to give you client-side an object hierarchy that looks like what you have server-side, but that a *very* leaky abstraction. It looks nice, but it is actually an illusion IMHO. It increases the complexity of the client-script, and it's only nicer if you actually intend to write a lot of client-side code and need a clean object model there. The truth is, most people don't want to touch client-side code, they want to write as little as possible. So far, strings have been just fine for all our scenarios. We do some simple parsing in the TreeView case, but TreeView is already a very complex control.
Another thing to consider is that the callback API is just that: a relatively low-level API that enables you to forget about the complexities of communicating cross-browser with the server. The idea is that people will build stuff on top of it. For example, I don't know if you checked out my samples, but there is a very interesting thingy in there that's called CallbackMultiplexer and it does something like a more strongly-typed callback in a very transparent way. You could very well build a control on top of our callback API that does marshalling in a more strongly-typed way, à la Web Service. After all, XML is just a way to marshal strongly-typed data using a string.
You know what, I think I agree with you that there are scenarios where you will want something more strongly-typed that a string, and I think I'll build a control that does that for you. I'll add it to the sample collection when it's ready. :)
Thanks for the comments.
# April 12, 2005 2:28 PM

Fregas said:

I think all of this: AJAX, Callbacks, XmlHttp, etc. just illustrate how crappy the HTML/HTTP model actually is right now. In windows and java applications, this kind of stuff is relatively simple. In the web world, we always seem to be trying to catch up to where the desktop world has been for ages. Hell, forget about catching up, we're just trying to get close!

Simple things like Drag & Drop or populating a drop down list without a refresh are a huge pain in the ass in DHTML/Javascript. They shouldn't be. The need not be. All this stuff in ASP.NET 2 and its like (while definitely nice to have) are just band-aids over the real problem. I think the bottom line is that we need to scrap HTML as the client/presentation layer and replace it with something else. Call me a dreamer... :)

Long live SmartClients! Long live XAML! Long live FLEX!
# April 12, 2005 3:28 PM

Bertrand Le Roy said:

Fregas: I agree completely that in an ideal world, we would all be doing declarative rich client applications. But the web is here to stay for at least a few more years, and it's still the best answer for a lot of application types. Not for technical reasons (even though the web is still superior for a number of things, like being very flexible with document layout), but for pragmatic reasons.
It is our job at ASP.NET to make Web application development less painful (if not fun altogether). Callbacks are one more step in this direction.
But if your application can be done using rich client technologies and not loose a large number of its customers along the way (think Amazon in WebForms... doh!), go ahead and do it, sure.
# April 12, 2005 3:35 PM

TrackBack said:

Brian Goldfarb sent me an email pointer to the latest ASP.NET Support Voice posting.&nbsp; This one covers...
# April 12, 2005 5:33 PM

Fregas said:

Well, thats the rub isn't it? -IF- the W3C or some other organization would come up with a standards based presentation layer that made sense and allowed all this rich interactivity, -AND IF- all the browser vendors would support this standard without devolving into more browser wars...well then, we'd all be better off: Users, Developers and Companies who want a good ROI.

Not likely to happen, unfortunately. There are whispers of it in things like Flex and Xaml, but no standard in sight yet.

ASP.NET definitely makes things easier in most ways (although not all.) But i'm tired of hearing about things like AJAX which is sugar frosting on top of layers and layers of crap. AJAX doesn't make my job easier. Instead, it gives people who don't know any better the impression that there is now a new technology to make the web "desktop-like" and make all their UI dreams come true. Come on. We don't all have the resources and know-how of google.
# April 13, 2005 10:10 AM

Bertrand Le Roy said:

Fregas, I understand what you're saying and I almost agree. I know that some customers/bosses can be a pain when they've read about a cool new buzzword like AJAX. So as a word, I agree that AJAX may be harmful to the industry in the sense that it diverts attention from the fact that the technology it describes is in no way a universal answer to the fundamental suckiness of the web.
On the other hand, I hope that our work (which predates the buzzword) will make it a little easier for people like you (our customers) answer your boss's or customer's demands. I'm not trying to amplify the buzz in any way, just to make it easier for our customers.
I agree, we're not all Google. Actually, Google Maps is a very impressive piece of software in many ways and reducing it to just an AJAX application is an insult to the talent of the Google engineers.
# April 13, 2005 2:06 PM

TrackBack said:

# April 15, 2005 5:54 PM

TrackBack said:

# April 15, 2005 8:21 PM

Cleve Littlefield said:

I disagree about the lack of need for strong typing. While full objects may be an allusion, something simple like supporting muliple parameters, not just a string input and a string output, is very useful. Here is a good example...

http://weblogs.asp.net/mschwarz/

Although this is a leaky abstraction, most of ASP.NET is a leaky abstraction of some sort or another...
# April 22, 2005 3:36 AM

Bertrand Le Roy said:

Cleve, with what exactly do you disagree? I never said there is no need for strong typing. One of my samples does precisely that: supporting multiple parameters...
About leaky abstrations, read my post about them: http://weblogs.asp.net/bleroy/archive/2004/12/02/274105.aspx
# April 23, 2005 10:37 PM

Sheetal Jain said:

Couldn't agree more - In our of our product we had written a strip out version of NanoXML parser as a applet to make server call to updaste <div> tags and this was back in 2000

# April 27, 2005 10:58 AM

TrackBack said:

wagnerblog.com &raquo; Fun with callbacks Part 1: What&#8217;s in the ASP.NET box?
# May 8, 2005 2:00 PM

TrackBack said:

Callbacks in 2.0
# May 19, 2005 2:27 PM

TrackBack said:

# May 25, 2005 11:58 AM

TrackBack said:

This entry is an introduction to ScriptCallbacks in ASP.NET 2.0 and a few observations and comments on the design and implementation. It seems this interface provides a core engine behavior that is pretty low level, but doesn't do anything to facility the actual process of data exchange between the client and server.
# June 6, 2005 6:03 PM

callback asp.net 2.0 « Private: .NET + OO concept said:

Pingback from  callback asp.net 2.0 &laquo; Private: .NET + OO concept

# July 23, 2007 12:44 AM