| By Timothy Stall | Article Rating: |
|
| March 17, 2006 08:30 AM EST | Reads: |
18,425 |
Web sites are based on a client-server model. While the client (usually a browser) can use client-side script such as JavaScript to do simple tweaking of existing data, getting new data requires a request to the server. The server does the heavy processing and makes a response back, which redraws the entire Web page. Most development required these interactions to be atomic so that each request to the server returns a completely new page.
The Problem with Postbacks
Postbacks, which are perhaps the most common way to communicate between the client and server, do exactly that. While this works, it has several problems:
- Posting back the entire page, as opposed to only what you need, sends a lot more traffic over the network. This hurts performance.
- Posting back prevents users from doing anything while they wait for the server to respond.
- Because you're re-creating the whole page (which also hurts performance), you must persist the state of the whole page. For example, all your JavaScript variables and controls without viewstate will be lost.
An Overview of Callbacks
Callbacks are a new feature in ASP.NET 2.0. They let a client script call the server without affecting the rest of the page (to those who have heard of AJAX or ATLAS, callbacks have similar functionality). The process is:
- On the client, a script calls the server, passing a string of data
- At the server, a method uses that data, and returns a new string (that you create) to a receiving function back at the client
- This receiving function is then triggered
Let's go over the technical implementation of the simplest callback, and then show both some advanced features as well as the limitations of callbacks. First, any page with callbacks must implement System.Web.UI.ICallbackEventHandler (see Listing 1).
This has two methods:RaiseCall-backEvent and GetCallbackResult. One approach is to use RaiseCall-backEvent for internal plumbing and let GetCallbackResult do the real work. RaiseCallbackEvent is fired first; it receives the client side data, and stores it in a member variable. GetCallbackResult is fired second; it accesses the client data via the member variable, does whatever manipulation you need, and then returns the new string. This return value will be passed to the receiving client function.
Still in the CodeBehind, we need to do some plumbing to register the client-side scripts (see Listing 2).
We need to register two client scripts: ReceiveCallback, which receives the callback when returning from the server, and CallServer, which calls the server (the names are intended to be obvious). These steps must always be run, not just in a "not PostBack" block, so we can abstract them to a method appropriately named "SetupAlways," and call that in the page load.
Meanwhile, at the client we add two simple scripts: StartCallback and ReceiveCallback (see Listing 3).
StartCallback is a custom function written by the developer whose sole purpose is to invoke CallServer and pass in a string of data. You can trigger it however you want, pass in any parameters you want, assemble the data however you want, and trigger the CallServer function based on whatever logic you want. The CallServer function itself was automatically created in the previous step.
ReceiveCallback is always triggered upon returning from the callback. We indicated that this was the receiving function when we registered it at the server. It expects a string that it can use for any JavaScript purpose - such as setting a message or modifying the DOM.
At this point, we have the full life cycle of a callback implemented. Let's build off of this with some more advanced topics.
Multiple Callbacks on a Single Page
A callback requires implementing an interface, but a single page can only implement one interface once. So how do we handle pages that need multiple callbacks, each with its own start and receiving functions? Simple - we prefix the data string with metadata to indicate which method to trigger.
Figure 1 illustrates this concept. First we have multiple client functions (StartA, StartB), which both call CallServer function [Step 1], but prefix the data string with an "A" or "B," respectively. The CallServer method still triggers the GetCallbackResult method on the server [Step 2], but now this method strips off the first character and uses it in a switch-case to call either ProcessA or ProcessB [Step 3]. Both processes return a string, but again prefix it with "A" or "B," and return it to the client [Step 4]. Finally, the client ReceiveCallback function strips off the first letter, and uses it to call the appropriate client receiving function, ReceiveA or ReceiveB [Step 5].
You can check the code download for an example of this. (Source code is available by viewing the article online in the DNDJ archives, http://dotnet.sys-con.com/read/issue/archives/, Vol. 4 iss. 3.)
Tips For Better Callbacks
With this infrastructure in place, these are several ways to maximize your benefit from callbacks.
First, UserControls can implement callbacks just like pages! This lets you incorporate callbacks into your reusable controls.
Second, while callbacks can't set the Response, they can still access all server resources such as the database, session, and page's viewstate. For example, suppose you want a callback to return a list of employees, excluding the current user. If the current user info was stored in session or viewstate, you could access that and manipulate the data appropriately at the server. This is helpful because it's easier to manipulate data on the server rather than the client due to the server's having better data structures and testability.
Third, often you'll want user interactions to change the page such as adding or removing table rows. For example, in postbacks a button click does this by re-creating HTML for the entire page. However in a callback, you keep the existing page, and therefore achieve this by modifying the DOM. Therefore you'll want to create client script libraries for easily modifying the DOM - such as adding or removing rows, hiding elements, or updating status messages. In some cases, you can have the server create the HTML for you, return that as the string, and then set the innerHTML property of a span or div.
Last, when we collect data to send to the server, it's often not just a single, primitive, string type. Rather, there are other data types (int, bool, dates), multiple values, and sometimes even a collection of objects that we need to send back to the server. For example, you may have an employee object with an ID (int) and Name (string) and you may want to send a group of these in the callback. One relatively easy way to handle this is with XML serialization. This has four steps:
- Write a simple entity class to hold the data
- Write a utility method to deserialize XML into a class
- In the client StartCallback function, create the XML string
- In the server, use the utility method to deserialize this and instantiate the object
You can use the built-in XML serialization methods to write a quick utility (see Listing 5).
You can then easily assemble the necessary XML via JavaScript (Listing 6).
Finally, you can deserialize at the server with the utility method shown in Listing 7.
Summary
Callbacks are a great new feature of ASP.NET 2.0. Like anything they have their pros and cons (Table 1).
Having this technique in your arsenal will fundamentally change how you develop, open up new doors that you wouldn't think possible before, and save you tons of time and performance. Given how easy callbacks are to implement, it's a technique well worth learning.
Published March 17, 2006 Reads 18,425
Copyright © 2006 SYS-CON Media, Inc. — All Rights Reserved.
Syndicated stories and blog feeds, all rights reserved by the author.
More Stories By Timothy Stall
Tim Stall is a software developer at Paylocity, an independent provider of payroll and human resource solutions. He can be contacted at tims@paylocity.com.
![]() |
Seenivasan 04/30/08 02:32:25 AM EDT | |||
hi, you have mentioned that the client script registration shud happen in "not PostBack" block which means in the Page_Load event. Is the following snippet is acceptable in the Page_Load event: if(!IsPostBack) |
||||
- Kindle 2 vs Nook
- Practical Approaches for Optimizing Website Performance
- SQL Anywhere Server and AJAX
- PowerBuilder Top Feature Picks
- The Difference Between Web Hosting and Cloud Computing
- PowerBuilder 12 and .NET
- Contrary Opinion: Why Silverlight is Good for Adobe
- Ajax in RichFaces 3.3, JSF 2 and RichFaces 4
- Wave on Ulitzer: Confessions of a Google Wave Fanboy
- Cloud Computing Best Practices
- AJAX World RIA Conference & Expo Kicks Off in New York City
- Rich Content Rotator for ASP.NET
- RIAs for Web 3.0 Using the Microsoft Platform
- Kindle 2 vs Nook
- Practical Approaches for Optimizing Website Performance
- Social Media Terrorists
- SQL Anywhere Server and AJAX
- SYS-CON's Cloud Expo Adds Two New Tracks
- PowerBuilder Top Feature Picks
- The Difference Between Web Hosting and Cloud Computing
- Google Maps and ASP.NET
- Crystal Reports XI & How It Has Changed
- Converting VB6 to VB.NET, Part I
- Creating Controls for.NET Compact Framework in Visual Studio 2005
- Where Are RIA Technologies Headed in 2008?
- How to Write High-Performance C# Code
- AJAX World RIA Conference & Expo Kicks Off in New York City
- Implementing Tab Navigation with ASP.NET 2.0
- i-Technology Photo Exclusive: Bill Gates & Steve Jobs In "Nerds"
- .NET Archives: Getting Reacquainted with the Father of C#





































