Interaction with a Web application can be initiated via a synchronous page
postback or an out-of-band postback, known as a client callback, from
the client to the server. The default ASP.NET Web page model uses
synchronous page postbacks, which are usually triggered on the client by
submitting an html form. During a page postback, the Web page and
controls are recreated and a new version of the entire Web page is rendered on
the client. In addition, most of the application logic is present on the
server-side. Unfortunately page postbacks often introduce a
great deal of processing overhead which can decrease performance. Since
the entire page must be reconstructed via a synchronous request to the
server, the client must wait for a response to continue
working. On the other hand, client callbacks can
improve performance and enhance
the end user experience when working with a Web
application. Callbacks utilize a set of technology
standards commonly referred to as AJAX (Asynchronous JavaScript and
XML).
AJAX includes:
-
Presentation content using XHTML and CSS
-
Dynamic display and interaction with XHTML (DHTML) using the Document
Object Model (DOM)
-
Data interchange using strings, often in XML format
-
Asynchronous data retrieval using an http request object
-
JavaScript - to bind everything together
Client callbacks can be synchronous or asynchronous. In either case, the
browser creates a new connection to send the callback to a remote server,
thus the callback is out-of-band. The contents of the entire page do
not need to be submitted, so the page lifecycle for a callback skips
events associated with rendering page contents on the
server. In addition, sending an asynchronous callback to a
server permits an end user to continue working in the client
application while the request is processed. When the response
is returned, the appropriate content in the Web page is updated without
refreshing the entire page. The diagrams below illustate the difference
between synchronous and asynchronous communication between a client application
and a server.
Synchronous
Asynchronous
The ASP.NET 2.0 implementation of client callbacks uses the Client
Callback Manager to provide an extensible callback framework. After
initial page load, subsequent requests to server-side code are made by a
client-side component, without refreshing the entire Web page. The page
runs a modified version of its normal life cycle (see diagram below) where
the page is initiated and loaded, but the page contents are not rendered.
Instead, a special method in the server-side code is
invoked, which processes the callback request content, then returns a
value to the browser that can be read by JavaScript function. The
JavaScript function uses technology inherent to the browser (e.g. DOM,
DHTML) to update Web page content dynamically. The Web page
continues to stay live while the request is being processed.
The diagram below illustrates the difference between the page lifecycle
sequence of events between a synchronous
page postback and a client callback. The Page.IsPostback
property will return true for both request types. The
Page.IsCallback property will return true only when the request is a client
callback.
Developing an ASP.NET 2.0 page that uses client callbacks is a two-step
process. First, create the server-side code that will be invoked by the
client. Second, create the client-side code to invoke the callback
request and process the response. Note that the message in the callback
request and response is always a string. The content and format of the
string is up to the developer. The request usually includes a string to
tell the server which action to perform and some user provided data. The
response usually contains content to be rendered on the client or a
set of data to trigger further actions.
Working with Callbacks in an
ASP.NET Web application
The following outline highlights the basic steps used to implement client
callbacks in an ASP.NET 2.0 Web page. In this example, the current time
on the Web server is returned and rendered in the client browser:
-
Implement the System.Web.UI.ICallbackEventHandler.
The ICallbackEventHandler interface can be implemented on a page or a Web
control. The interface contains two key methods:
RaiseCallbackEvent(string EventArgs) and GetCallbackResult().
RaiseCallbackEvent() receives the message in the callback request sent from the
client. It can be designed to parse the message and
determine what server-side logic will be executed. Once the server-side
code is finished, it creates a string of values to be sent to the
client using the GetCallbackResult() method. Here is
an implementation example of both methods in the code-behind page
Default.aspx.cs. The eventArgument will be updated via a callback request
from the client. This is discussed in greater detail
below.
[C#]
public partial class Default : System.Web.UI.Page, System.Web.UI.ICallbackEventHandler
{
string returnstring;
string ICallbackEventHandler.GetCallbackResult()
{
return returnstring;
}
void ICallbackEventHandler.RaiseCallbackEvent(string eventArgument)
{
if (eventArgument == "getservertime")
{
returnstring = DateTime.Now.ToString();
}
}
-
Call the GetCallbackEventReference method on the Page class.
The GetCallbackEventReference method creates a JavaScript string in
the client Web page to start the callback. The usage
and method parameters are listed below:
Usage: GetCallbackEventReference(control, argument, clientCallback, context, clientErrorCallback, useAsync);
|
Parameter Name |
Description |
| control |
The control or the page which implements ICallbackEventHandler. |
| argument |
Name of a client-side JavaScript variable. References the string
sent to the RaiseCallbackEvent method via the eventArgument parameter. |
| clientCallback |
Name of the client-side JavaScript function which will
receive the result of a successful server event. |
| context |
Name of a client-side JavaScript variable. Usually used to determine
the content of the message (argument) in the callback request. The value of the
variable will be stored on the client as the context parameter associated
with a callback. |
| clientErrorCallback |
Name of the client-side JavaScript function which will receive the
callback result when an error occurs. |
| useAsync |
Boolean to determine whether a synchronous or asynchronous callback
is made to the server. |
Here is an example of the method used in code. The
sCallBackFunctionInvocation member variable is a public string, global to
the Page class:
[C#]public string sCallBackFunctionInvocation;
protected void Page_Load(object sender, EventArgs e)
{
sCallBackFunctionInvocation = Page.ClientScript.GetCallbackEventReference(this,
"message", "processMyResult", "context", "processMyError", true);
}
At runtime, when the Web page is first loaded, the
GetCallbackEventReference method generates a JavaScript string
that contains the WebForm_DoCallback function with the parameters
listed above. The next step will discuss adding a
reference to this function in client-side code.
-
Create the client-side code to trigger the callback and process the
response.
Implementing System.Web.UI.ICallbackEventHandler and calling
GetCallbackEventReference will add something similar to the following
script tag in your aspx page at runtime:
<script src="/WebAppName/WebResource.axd?d=TqQApA1CcEIyShhLjzTczw2&t=632657807109074470" type="text/javascript">
</script>
WebResource.axd is a new HTTP Handler in ASP.NET 2.0 that
enables Web page and Web control developers to download resources that are
embedded in an assembly. The System.Web.dll contains
a JavaScript resource that contains the
WebForm_DoCallback function. The format of this URL is
WebResource.axd?d=encrypted identifier&t=time stamp value
. The "d" refers to the requested Web resource and is an encrypted
string of the assembly name and resource name. The "t" is the
timestamp for the requested assembly, which can help in determining if there
have been any changes to the resource. At runtime, the
JavaScript resource is downloaded to the client.
In many cases, callbacks within a browser are managed using the
XMLHttpRequest object. More specifically, the ASP.NET 2.0 Callback
Framework includes JavaScript content to
support callbacks. The JavaScript
function which initiates and manages callbacks in
the client browser is WebForm_DoCallback. It creates an
ActiveX object, Microsoft.XMLHTTP for Internet Explorer browsers or a
native XMLHttpRequest object for other browsers to manage HTTP
communication with a Web application on the server. The Microsoft.XMLHTTP
object is packaged with the Microsoft XML Document Object Model, part
of the MSXML set of components.
The following code provides an example of the HTML content in an aspx page
configured to work with callbacks. The edits to the code
involve two steps:
-
Add an HTML element and a JavaScript function to create a callback
request. In the HTML code below, the click event of
an HTML button triggers a call to the JavaScript function
getServerTime, which in turn calls WebForm_DoCallback. The
message variable is set to 'getservertime' which is used by the server to
determine which action to execute. The server variable
<%=sCallBackFunctionInvocation%> is translated to WebForm_DoCallback('__Page',
message, processMyResult, context, postMyError, true)
at runtime.
-
Add two JavaScript functions to process the callback response and update the
page. The processMyResult function takes the callback response string and
updates the text content of a div tag in the HTML page. Note, this
happens dynamically so other objects in the page are not redrawn. The
postMyError function receives the callback message if an error was thrown on
the server. In this case, it pops up an alert box.
<html>
<head>
<title>Untitled Page</title>
<script language="javascript" type="text/javascript">
function getServerTime()
{
var message = 'getservertime';
var context = 'Page1';
<%=sCallBackFunctionInvocation%>
}
function processMyResult(returnmessage, context){
var timediv = document.getElementById('timelabel');
timediv.innerHTML = returnmessage;
}
function postMyError(returnmessage, context){
alert("Callback Error: " + returnmessage + ", " + context);
}
</script>
</head>
<body>
<form id="form1" runat="server">
<input type="button" value="Get Server Time" onclick="getServerTime();" />
<div id="timelabel"></div>
</form>
</body>
</html>
The following diagram illustrates a callback event at runtime.
The green circles indicate the order in which events occur to
initiate and process the callback. A short description for each
event is provided below:
1. After the Web page loads, the onClick event of an HTML button is triggered
which calls the user-defined getServerTime JavaScript function.
2. The getServerTime function sets the message and context variables to be
sent to the server and calls the ASP.NET 2.0 defined WebForm_DoCallback
function to create and send the callback request.
3. A new XMLHttpRequest object is created to send and
receive the asynchronous call to\from the server.
4. The XMLHttpRequest object posts the HTTP request to the server
containing the message. On the server, the RaiseCallbackResult
method parses the argument (message) and executes some business logic - in this
case, it converts the time on the server to a string. The
GetCallbackResult method passes this string back to the XMLHttpRequest
object waiting on the client.
5. The ASP.NET 2.0 WebResource for callbacks directs the callback
response string to the registered callback response function, the
user-defined processMyResult function.
6. The processMyResult function uses the content of the callback response
string to dynamically update HTML in the Web page. In this case,
it inserts HTML into an existing <div> tag to display the
server time.