Some thoughts about server callbacks and Ajax.NET

Looking back at all the feedback I got from my ongoing Fun with callbacks series, I understood a few things about what most people expect from an Ajax-like framework.

Our callback feature's implementation seems to be surprising for most of our users. It's actually quite different from the very lean and simple approach most Ajax samples are adopting. Our callbacks are an integral part of the page lifecycle and thus carry with them the weight of the state of the page. Most users seem to expect to just query data out-of-band, not necessarily trigger server-side events in the stateful context of the page. Why is that?

I think the main reason for this difference in the expectations and what we delivered is that we tend to think as control developers, whereas most of our users think as application or page developers.

If you are a control developer, nothing outside of your control should be considered a reliable asset simply because it's not responsible for it. Many Ajax control developers think like page developers and expose properties that will point the control to some service url that will feed them data. We avoid that kind of architecture because we want our page developers to be able to drag and drop the control to the page in the designer and have it working immediately. We don't want them to have to write a separate page, handler or web service for that. We want the control and the page to be self-contained components. To achieve that goal, we need the out-of-band calls to go back to the page itself and not to some external url.

We also want the callback event to be able to access all the richness and statefulness of the page and its control tree. In other words, we want a callback-enabled control to be able to interact fully with its context on the page (data sources are the main example).

Finally, we want the callback model to be as close as possible to the existing postback model: we want simple events on simple controls.

What we have is controls that look like ordinary controls (visually and in their object model) but can have better responsiveness using callbacks, so that developers using our technology can start using them and get the benefits of Ajax without having to know anything about client-side scripting or XmlHttp. And we're also exposing an API so that control developers can create new controls like the ones we're shipping with ASP.NET 2.0 (TreeView, GridView, DetailsView).

Now what about the page or application developer? This developer is composing existing controls, orchestrating their relationsships with each other and the other layers of the application using event handlers.

It's this last point that is relevant to Ajax: the orchestration with other layers of the application. Typically, the page will exchange data with other layers. Remember, this is very different from callbacks which are actually controls triggering events on themselves.

If you're going to exchange data with another layer, you don't really want all the extra weight of page statefulness. What you want is the data and nothing else. This layer may be exposed by some kind of web service or REST handler, but is not necessarily something you want exposed on the page surface. Ajax.NET and other existing Ajax frameworks deliver quite well on this point even though they are unable to do what we do with callbacks. So they answer a need that we don't answer well enough with callbacks, and vice versa.

What I'm saying is that both approaches are complementary. That's one thing we've understood from the feedback and something we're going to address with the Atlas framework (among other things).

5 Comments

  • I'm glad to see both.



    I only looked at the Schwartz Interactive AJAX, but it is so simple to use.

    You don't need to know about xmlHttp to use it and on the server you could just use an ordinary aspx page with the functions. In pages where you want to use those functions you call a register for ajax method.

  • Any solution that requires developers to manually serialize their wonderful objects and then do something meaningful in JavaScript with it is gonna fall flat on it's face. Until such time as good tool support for JavaScript exists, and developers learn that JavaScript is actually OO, even poor developers are going to realize that their code is unmanageable and hackish.





    Ajax.Net might provide a "leaky abstraction" (thank's joel for that one!), it's still pretty productive:



    var ds = response.value;

    for (var i = 0; i < ds.Tables[0].Rows.length; ++i)

    {

    var firstName = ds.Tables[0].Rows[i].FirstName;

    var lastName = ds.Tables[0].Rows[i].LastName;

    }



    for the win!!



    Karl



  • (oh, and yes, we know of the Dart controls and of several other similar libraries. They're great and I can only encourage people to use them if they answer their needs.)

  • Friday 5:30 pm idea...



    > One solution we've been thinking about for Orcas involves making the ViewState

    > less monolythic and enabling the page to be broken into smaller mini-pages that

    > would have their own isolated state and where local sequentiality of the callbacks

    > would be less of a problem. The problem with such a model is that it becomes

    > more difficult for these mini-pages to communicate with the rest of the page.



    How about implementing better AJAX support for WebParts based solutions using each webpart as granularity? In such a scenario, "breaking pages into smaller mini-pages" = "defining webparts". WebParts communicate with each other using a provider-consumer connection model. The webpartmanager knows all the dependencies that exist between webparts at runtime.



    In this model, WebParts would serve as the autonomous logical parts of the UI. The page's postback and state mechanism would be delegated to each webpart. Each webpart would then be responsible for it's own state and for posting back to the server. Upon return of a postback, the webpart's display and state would be updated. Just like a normal page postback, but scoped to a webpart and using AJAX to refresh only part of the UI.



    Now, what if a webpart's state is dependent on the state of another webpart. For example, a master webpart and a detail Webpart. When the selection in the master webpart changes, the detail must be updated accordingly. If each webpart acts independently for postback, the detail will never be updated. However, in the webparts framework, dependencies between webparts are declared through a provider-consumer connection model. Therefore, when a webpart posts back, it is possible to know dependent webparts by finding all consumers of any connection provided by the parent webpart. To answer the dependent webparts problem, upon a webpart postback, a simple rule could be to execute postback logic for each dependent webpart as well as for the parent webpart. Upon return, update state and display for all the webparts implicated in the postback.

  • Etienne, WebParts and callbacks/ajax sure are interesting scenarios for the Orcas timeframe as well as for Atlas, but at this point we don't want to force WebParts as the infrastructure people would need to use to get these features. Portal features and better callbacks are orthogonal and we're more thinking about a user control or panel, which can be combined with WebParts but do not force one to use them.

    It's interesting to consider, though, because of the way WebParts maintain and persist state, which is very different from what ordinary Controls do.

    Thanks for the feedback.

Comments have been disabled for this content.