Click to Rate and Give Feedback
Collapse All/Expand All Collapse All
This page is specific to
Microsoft Visual Studio 2008/.NET Framework 3.5

Other versions are also available for the following:
ASP.NET
Implementing Client Callbacks Programmatically 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 can 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.

There are several options for automating client callbacks in an ASP.NET Web page. AJAX features in ASP.NET such as the UpdatePanel server control can automate asynchronous partial-page updates for you, and the Web service communication feature can automate asynchronous Web service calls.

For an overview of AJAX features in ASP.NET that automate client callbacks for you, see the following topics:

You can also write your own client script to implement client callbacks directly. This topic discusses how to implement your own client callbacks for asynchronous communication between the client and server.

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

  • 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. 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 referred to as the client callback function.

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

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

To run server code from client script without performing a postback, you must implement several 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.

Visual Basic
Partial Class CallBack_DB_aspx
    Inherits System.Web.UI.Page
    Implements System.Web.UI.ICallbackEventHandler
C#
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 examples:

Visual Basic
<%@ Page Language="VB" %>
<%@ Implements Interface="System.Web.UI.ICallbackEventHandler" %>
C#
<%@ 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 example:

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

    ' Processes a callback event on the server using the event
    ' argument from the client.

End Sub
C#
public void RaiseCallbackEvent(String eventArgument)
{
    // Processes a callback event on the server using the event
    // argument from the client.
}

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

Visual Basic
Public Function GetCallbackResult() As String Implements _
    System.Web.UI.ICallbackEventHandler.GetCallbackResult

    ' Returns the results of a callback event to the client.
    Str(DateString = DateTime.Now.ToString())

    Return DateString

End Function
C#
public string GetCallbackResult()
{
    // Returns the results of a callback event to the client.
    string dateString = DateTime.Now.ToLongDateString();

    return dateString;
}

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 that you will use to 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 example shows how to dynamically create a function named CallServer that invokes the callback.

Visual Basic
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
C#
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 example shows some markup that could be used to invoke the callback and process its return value:

Visual Basic
<input type="button" value="Callback" 
    onclick="CallServer('1', alert('Callback sent to Server'))" />
<br />
<span id="Message"></span>
C#
<input type="button" value="Callback" 
    onclick="CallServer('1', alert('Callback sent to Server'))" />
<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 example:

Visual Basic
function ReceiveServerData(arg, context) {
    Message.innerText = "Date from server: " + arg;
}
C#
function ReceiveServerData(arg, context) {
    Message.innerText = "Date from server: " + arg;
}

Complete Example

The following example shows the Web page based upon which the previous examples were based:

Visual Basic
<%@ Page Language="VB" AutoEventWireup="false" %>
<%@ 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 runat="server">
    <title>Client Callbacks</title>
    <script runat="server">
        Public Sub RaiseCallbackEvent(ByVal eventArgument As String) _
            Implements System.Web.UI.ICallbackEventHandler.RaiseCallbackEvent

            ' Processes a callback event on the server using the event
            ' argument from the client.

        End Sub

        Public Function GetCallbackResult() As String Implements _
            System.Web.UI.ICallbackEventHandler.GetCallbackResult

            ' Returns the results of a callback event to the client.
            Str(DateString = DateTime.Now.ToString())

            Return DateString

        End Function

        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
    </script>
    <script type="text/javascript">
        function ReceiveServerData(arg, context) {
            Message.innerText = "Date from server: " + arg;
        }
    </script>
</head>
<body>
    <h2>Client Callbacks Without Postbacks</h2>
    <form id="form1" runat="server">
       <input type="button" value="Callback" 
           onclick="CallServer('1', alert('Callback sent to Server'))" />
       <br />
       <span id="Message"></span>
   </form>
</body>
</html>
C#
<%@ Page Language="C#" AutoEventWireup="true"  %>
<%@ 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 runat="server">
    <title>Client Callbacks</title>
    <script runat="server">
        public void RaiseCallbackEvent(String eventArgument)
        {
            // Processes a callback event on the server using the event
            // argument from the client.
        }

        public string GetCallbackResult()
        {
            // Returns the results of a callback event to the client.
            string dateString = DateTime.Now.ToLongDateString();

            return dateString;
        }

        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);
        }
    </script>
    <script type="text/javascript">
        function ReceiveServerData(arg, context) {
            Message.innerText = "Date from server: " + arg;
        }
    </script>
</head>
<body>
    <h2>Client Callbacks Without Postbacks</h2>
    <form id="form1" runat="server">
       <input type="button" value="Callback" 
           onclick="CallServer('1', alert('Callback sent to Server'))" />
       <br />
       <span id="Message"></span>
   </form>
</body>
</html>
Tags What's this?: Add a tag
Community Content   What is Community Content?
Add new content RSS  Annotations
error in the code      Jinjav   |   Edit   |   Show History

public String RaiseCallbackEvent(String eventArgument){} declaration is wrong.

It should be public void RaiseCallbackEvent(String eventArgument){} instead.

Tags What's this?: error (x) Add a tag
Flag as ContentBug
icallbackeventhandler bug      rizzy ... Noelle Mallory - MSFT   |   Edit   |   Show History

How come making two calls in one go to CallServer() triggers RaiseCallbackEventHandler() on the server side twice but only triggers ReceiveServerData() only once on the client side? All the data returned from previous calls is lost since the ReceiveServerData()argument only gets data returned from the most recent call to the server. Is this a bug?

[Noelle Mallory - MSFT] Please post questions to the MSDN Forums at http://forums.microsoft.com/msdn. You will likely get a quicker response through the forum than through the Community Content.

Routing WebForm_DoCallback back to the server      Tebe   |   Edit   |   Show History
As above, there seems to be some synchronization issues between client and server. It has been noted that when using this technology in a custom server side web control, that the call back is not routed to the correct instance of the server side control code. This statement is based on a debug analysis of one of three client side calls defined to perform WebForm_DoCallback. In each case the event argument is set to the name of the control instance, in addition to the first parameter which is suppposed to be the controlId. On the server side the incoming argument is compared to the "this.ClientId". Unlike the above case, all three do fire, and return events are fired. However, all three client side events are routed to the same server instance of the control.
Processing
© 2009 Microsoft Corporation. All rights reserved. Terms of Use | Trademarks | Privacy Statement | Site Feedback
Page view tracker