Web Development

Limit postbacks with ASP.NET 2.0 client callbacks

Learn how to reduce page postbacks by implementing page callbacks in ASP.NET 2.0 pages using the ICallbackEventHandler interface. It allows you to easily reduce page reloads thus improving the user experience.

Developers have been grappling with the stateless nature of the Web since its inception. That is, once a page has been requested and loaded, the connection to the server is gone.

The AJAX movement has put the spotlight on the XMLHTTP object, which enables server communication in the background. ASP.NET 2.0 provides its own way to make server requests without disturbing the user.

Disconnected

Over the years, there have been various solutions that circumvent the stateless limitation of Web applications, with the focus on reducing the number of page calls or reloads to avoid hampering the user experience. For example, many developers used hidden frames to serve as data sources so data could easily be sent to or retrieved from the hidden frame page. Also, some developers chose to load everything with the initial load, so subsequent page loads are reduced.

The problem arises when it is absolutely necessary to make a server call. This is where the AJAX group of technologies enters the picture. AJAX utilizes the XMLHTTP object, along with XML and client side scripting (aka JavaScript) to handle asynchronous server calls.

ASP.NET model

The default behavior of an ASP.NET page begins when the page is requested by a user and loaded in the requesting client. The user interacts with the page via various actions like clicking a button. These actions may trigger a call to the server called a postback (i.e., the page is posted back to the host with a new version of the page reloaded as a result of the action).

Page postbacks come with a price. For example, client state may be lost, and communicating with the server interrupts the user experience as they wait during communication and page reload. AJAX methodologies address these issues by facilitating asynchronous communication with a server while the user experience is not interrupted. A similar approach may be implemented in ASP.NET 2.0 through the use of the ICallbackEventHandler interface.

Implementing a callback

A callback is a function associated with a specific user interface component. The callback performs a certain action in response to a component event. The event can be any one of the many available mouse clicks or any other event.

Implementing callbacks in an ASP.NET 2.0 page has a few differences from standard Web pages. The following list outlines the necessary changes to the page code:

  • The page must implement the ICallbackEventHandler interface.
  • The RaiseCallbackEvent method of the ICallbackEventHandler interface must be implemented by the page. This method is invoked to perform the callback on the server.
  • The page must implement the GetCallbackResult method of the ICallbackEventHandler interface. This method will return the callback result to the client.

With these code changes in place, the callback may be utilized on the client side of the page (HTML source). The Web page must include client-side functions to perform the actual server request along with receiving the results from the server request.

The C# page in the following code listing provides a demonstration of implementing a callback. 

<%@ Page Language="C#" %>

<%@ Implements Interface="System.Web.UI.ICallbackEventHandler" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"

"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html><head>

<title>ASP.NET Callback</title>

<script language="C#" runat="server">

protected String returnValue = "";

protected void Page_Load(object sender, EventArgs e) {

String callbackRef;

String callbackScript;

callbackRef = Page.ClientScript.GetCallbackEventReference(this, "arg", "GetData", "context");

callbackScript = "function CallServer(arg, context) {" + callbackRef + "; }";

Page.ClientScript.RegisterClientScriptBlock(this.GetType(), "CallServer",

callbackScript, true);

}

public string GetCallbackResult() {

return returnValue;

}

public void RaiseCallbackEvent(String eventArgument) {

returnValue = "The current time is: " + DateTime.Now.ToString();

}

</script>

<script type="text/javascript">

function GetData(arg, context) {

Results.innerHTML = arg;}

</script>

</head><body>

<form id="frmCallback" name="frmCallback" runat="server">

<input type="button" value="Callback" onclick="CallServer(1, Results.innerHTML = 'Callback')"/>

<br />

<span id="Results">Test</span>

</form></body></html>

A few notes on the code:

  • The page's Page_Load event sets a reference to the callback function (GetData) via the GetCallbackEventReference method available in the page's ClientScript property. The method accepts these parameters: a reference to the page; the name of the argument by which the data are passed; the name of the client script function that receives the callback data; and an argument that passes any context you want. In this example, the context isn't used.
  • The function that will be used to call the server is created (callbackScript variable in the example) with the function reference included. Also, the arguments that are accepted by the generated function must match the names passed to the GetCallbackEventReference method. Finally, the callback script is registered on the page via the RegisterClientScriptBlock method of the Page object's ClientScript property.
  • The GetCallbackResult method provides the output (string) returned by the callback. In this example, the current date and time (on the server) is returned.
  • The client function that receives callbacks is loaded in the header portion of the page (GetData in the example). The function must be named to match the name passed in the call to the GetCallbackEventReference method. The function accepts two string values for the return value and an optional second value for the context value that is passed back from the server.
  • The button on the page is tied to the callback function. In this example, the HTML span object receives the callback result.

A smooth user experience

Avoiding page reloads simplifies the user experience and can reduce the amount of data sent back and forth between the client and server. You can use the AJAX approach to provide this functionality; you can also use ASP.NET 2.0's callback support. The applications for these techniques are endless, and anything that improves the user experience is good for business.

Tony Patton began his professional career as an application developer earning Java, VB, Lotus, and XML certifications to bolster his knowledge.

About

Tony Patton has worn many hats over his 15+ years in the IT industry while witnessing many technologies come and go. He currently focuses on .NET and Web Development while trying to grasp the many facets of supporting such technologies in a productio...

14 comments
npraveena
npraveena

I have an issue in my application: The client side javascript function does not return anything. when i try to display it using alert - all i get is undefined. any suggestions? please help

TexasJetter
TexasJetter

Ok, got the updated code working (and even cobbled togehter a VB version :) - and I think I understand the concept - simply stuff new content into the InnerHTML. I have been wondering how to get this done in ASP.NET. Thanks so much for the tip. Now to my question - is this not essentially what the asp:ScriptManager and asp:Update panels (from the ASP.NET Ajax framework) are doing? While the example is simple, I can eaisly see a complex page getting, well, complex. Managing multiple callback targets/functions in the manner demonstrated could get very tricky. Just wondering if there is an upside to to this method over the Updatepanels.

magillj
magillj

This seems pretty complicated when compared to Page Methods. Can anyone comment on the pros and cons of Callbacks and Page Methods?

TexasJetter
TexasJetter

Interesting concept that I would love to explore, but I am a VB.NET person, and I cannot seem to get the supplied code to work. I receive a complie error "The name 'DateNow' does not exist in the current context" when I run the code. If I remove the "+ DateNow.ToString()" portion the page compiles, but all I see is a flash of 'CallBack' in the span, but no 'The current time is:' as a result. What am I missing?

maciej.komorowski
maciej.komorowski

Very nice idea presented! I guess those two small places in the code where it does not work as expected are just to make us more cautious and learn better ;) Good job.

MadestroITSolutions
MadestroITSolutions

My knowledge on this subject is limited but I believe the main idea behind this is that rather than submit/reload the entire page, you issue a call to the page via client script. The call is specially crafted to cause a reload of the page on the server side, invocation of some method and subsequent return of data in the form of a string to the client, which in turn updates the page HTML. It seems to me like this IS AJAX integrated into the .NET Framework via marker interfaces and helper functions.

aspatton
aspatton

The DateNow line should read DateTime.Now.ToString(). The corrected code listing has been posted.

EM1109
EM1109

Good concept. Code fix: DateTime.Now.ToString(); I understand intuitively what you are trying to do; however, the code does not return the date to the span tag with id of Results. You briefly see the text 'Callback' upon hitting the button.

ahin4114
ahin4114

Can't see the code here, the link for listing a just open a new window with the article in it...

slawrence
slawrence

For me, the initial code link opened a new window showing the original article, but clicking the code link in the new window opened another window which did show the code.

MaryWeilage
MaryWeilage

Dear slawrence, Thank you for notifying us about this issue with the code listing. The code is now inserted directly into the article. Thank you, Mary Weilage TechRepublic

Editor's Picks