Implementing Client Callbacks Without Postbacks in ASP.NET Web Pages

In the default model for ASP.NET Web pages, the user interacts with a page and clicks a button or performs some other action that results in a postback. The page and its controls are re-created, the page code runs on the server, and a new version of the page is rendered to the browser. However, in some situations, it is useful to run server code from the client without performing a postback. If the client script in the page is maintaining some state information (for example, local variable values), posting the page and getting a new copy of it destroys that state. Additionally, page postbacks introduce processing overhead that can decrease performance and force the user to wait for the page to be processed and re-created.

To avoid losing client state and not incur the processing overhead of a server roundtrip, you can code an ASP.NET Web page so that it can perform client callbacks. In a client callback, a client script function sends a request to an ASP.NET Web page. The Web page runs a modified version of its normal life cycle — the page is initiated and its controls and other members are created, and then a specially marked method is invoked. The method performs the processing that you have coded and then returns a value to the browser that can be read by another client script function. Throughout this process, the page is live in the browser.

Several Web server controls use client callbacks. For example, the TreeView control uses client callbacks to implement its populate on demand functionality. For more information see TreeView Web Server Control Overview.

Components of Client Callbacks

Creating an ASP.NET page that implements client callbacks is similar to creating any ASP.NET page, with a few these differences. The page's server code must:

  • Implement the ICallbackEventHandler interface. You can add this interface declaration to any ASP.NET Web page.

  • Provide an implementation for the RaiseCallbackEvent method. This method will be invoked to perform the callback on the server.

  • Provide an implementation for the GetCallbackResult method. This method will return the callback result to the client.

In addition, the page must contain three client script functions that perform the following actions:

  • One function calls a helper method that performs the actual request to the server. In this function, you can perform custom logic to prepare the event arguments first, and then you can send a string as a parameter to the server-side callback event handler.

  • Another function receives (is called by) the result from the server code that processed the callback event, accepting a string that represents the results. This is called the client callback function.

  • A third function is the helper function that performs the actual request to the server, which is generated automatically by ASP.NET when you generate a reference to this function using the GetCallbackEventReference method in server code.

Both client callbacks and postbacks are requests for the originating page, thus, client callbacks and postbacks are recorded in Web server logs as a page request.

Implementing the Appropriate Interfaces in Server Code

To successfully run server code from the client without performing a postback, you must implement the appropriate interfaces in server code.

Declaring the ICallbackEventHandler Interface

You can declare the ICallbackEventHandler interface as part of the class declaration for the page. If you are creating a code-behind page, you can declare the interface by using syntax such as the following.

Partial Class CallBack_DB_aspx
    Inherits System.Web.UI.Page
    Implements System.Web.UI.ICallbackEventHandler
public partial class CallBack_DB_aspx : 
    System.Web.UI.Page, System.Web.UI.ICallbackEventHandler

If you are working in a single-file page or user control, you can add the declaration by using an @ Implements directive in the page, as in the following code examples:

<%@ Page Language="VB" %>
<%@ Implements Interface="System.Web.UI.ICallbackEventHandler" %>
<%@ Page Language="C#" %>
<%@ Implements Interface="System.Web.UI.ICallbackEventHandler" %>
NoteNote

The interface name is case-sensitive.

Creating a Server Callback Method

In server code, you must create a method that implements the RaiseCallbackEvent method and a method that implements the GetCallbackResult method. The RaiseCallbackEvent method takes a single string argument instead of the usual two arguments that are typically used with event handlers. A portion of the method might look like the following code example.

Public Sub RaiseCallbackEvent(ByVal eventArgument As String) _
    Implements System.Web.UI.ICallbackEventHandler.RaiseCallbackEvent

End Sub
public void RaiseCallbackEvent(String eventArgument)
{

}

The GetCallbackResult method takes no arguments and returns a string. A portion of the method might look like the following code example:

Public Function GetCallbackResult() As String Implements _
    System.Web.UI.ICallbackEventHandler.GetCallbackResult
    Return aStringValue
End Function
public string GetCallbackResult()
{
    return aStringValue;
}

Creating Client Script Functions

You must add client script functions to the page to perform two functions: send the callback to the server page and receive the results. Both client script functions are written in ECMAScript (JavaScript).

Sending the Callback

The function to send the callback is generated in server code. The actual callback is performed by a library function that is available to any page that implements the ICallbackEventHandler interface. You can get a reference to the library function by calling the page's GetCallbackEventReference method which is accessible through the ClientScript property of the page. You then build a client function dynamically that includes a call to the return value from the GetCallbackEventReference method. You pass to that method a reference to the page (this in C# or Me in Visual Basic), the name of the argument by which you will pass data, the name of the client script function that will receive the callback data, and an argument that passes any context you want.

When you have built the function, you inject it into the page by calling the RegisterClientScriptBlock method.

The following code example shows how to dynamically create a function named CallServer that invokes the callback.

Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) _
    Handles Me.Load
    Dim cm As ClientScriptManager = Page.ClientScript
    Dim cbReference As String
    cbReference = cm.GetCallbackEventReference(Me, "arg", _
        "ReceiveServerData", "")
    Dim callbackScript As String = ""
    callbackScript &= "function CallServer(arg, context)" & _
        "{" & cbReference & "; }"
    cm.RegisterClientScriptBlock(Me.GetType(), _
        "CallServer", callbackScript, True)End Sub
void Page_Load(object sender, EventArgs e)
{
    ClientScriptManager cm = Page.ClientScript;
    String cbReference = cm.GetCallbackEventReference(this, "arg",
        "ReceiveServerData", "");
    String callbackScript = "function CallServer(arg, context) {" +
        cbReference + "; }";
    cm.RegisterClientScriptBlock(this.GetType(),
        "CallServer", callbackScript, true);
}

The names of the arguments that are accepted by the function you are generating must match the names of the values that you pass to the GetCallbackEventReference method.

The following code example shows some markup that could be used to invoke the callback and process its return value:

<input type="button" value="Callback" 
    onclick="CallServer(1, alert('Callback'))"/>
<br />
<span id="Message"></span>
<input type="button" value="Callback" 
    onclick="CallServer(1, alert('Callback'))"/>
<br />
<span id="Message"></span>

Receiving the Callback

You can write the client function that receives callbacks statically in the page. The function must be named to match the name that you pass in the call to the GetCallbackEventReference method. The receiving function accepts two string values: one for the return value and an optional second value for the context value that is passed back from the server.

The function might look like the following code example:

<script type="text/javascript">
function ReceiveServerData(arg, context)
{
    Message.innerText = 'Processed callback.';
}
</script>

See Also

Reference

ClientScriptManager

Concepts

Client-Callback Implementation (Visual Basic) Example
Client-Callback Implementation (C#) Example