All docs
V21.2
21.2
21.1
20.2
The page you are viewing does not exist in version 20.2. This link will take you to the root page.
20.1
The page you are viewing does not exist in version 20.1. This link will take you to the root page.
19.2
The page you are viewing does not exist in version 19.2. This link will take you to the root page.
19.1
The page you are viewing does not exist in version 19.1. This link will take you to the root page.
18.2
The page you are viewing does not exist in version 18.2. This link will take you to the root page.
18.1
The page you are viewing does not exist in version 18.1. This link will take you to the root page.
17.2
The page you are viewing does not exist in version 17.2. This link will take you to the root page.

Callbacks

  • 8 minutes to read

Callbacks allow you to call server code asynchronously and obtain the callback result without a postback. The callback result contains only the updated part of a page. This reduces the network traffic and response time.

Page Lifecycle

Callbacks reduce the page lifecycle. The image below demonstrates a simplified diagram of a postback and callback request processes.

Page Lifecycle on Callbacks and Postbacks

Page Lifecycle During a Postback

In postback mode, an action submits a web page to the server for processing. The server runs the full page lifecycle and sends the new page markup to the client. The client reloads the enire page.

Page Lifecycle During a Callback

In callback mode, an action triggers an asynchronous request to be sent to the web server. The server runs a modified version of a normal page lifecycle where the following steps are skipped:

  • The SaveViewState() method is not called. View state information is retrieved and available on the server, but changes made to the state do not persist.
  • The PreRender event is not raised.

As a result, less data is sent back to the client and only specific parts of the page is refreshed.

Use the IsCallback property to determine whether the page request is the result of a callback.

Limitations

  • You cannot update an external control in a callback of another control.

    A callback result contains only the updated part of a page. You can find different workarounds in the following topic: Update a Control in a Callback of Another Control (Workarounds).

  • You cannot download a file during a callback.

    When a callback is sent, a client-side object awaits a proper callback result. While the file is downloading, the callback result is cleared and the file content is written to the server response directly. In this case, client-side objects cannot determine the result that is sent to the browser and their state becomes broken. For information on how to upload a file on the client, see the following topic: Download a File on the Client

DevExpress Control Callbacks

Complex DevExpress ASP.NET controls send callbacks to update their own rendering. For instance, ASPxGridView sends callbacks to filter, sort, or edit data. The data is downloaded in the background, invisible to the user. On the client, the data is collected by a JavaScript function and used to update the control state (for instance, to display a new page of records).

Send a Custom Callback

DevExpress controls that support custom callbacks implement the client-side PerformCallback method. Call this method to send a callback to the server. You can pass information from the client side to the server as the method’s parameter. On the server, the PerformCallback method raises the CustomCallback event and passes the specified parameter to the event.

<dx:ASPxRichEdit ID="ASPxRichEdit1" runat="server" ClientInstanceName="richEdit" OnCallback="re_Callback" />

<dx:ASPxFileManager ID="FileManager" runat="server">
    <Settings RootFolder="Rich_documents" ThumbnailFolder="~/Thumb/" AllowedFileExtensions=".docx,.doc,.rtf,.txt"/>
    <ClientSideEvents SelectedFileChanged="onSelectedFileChanged"/>
</dx:ASPxFileManager>
function onSelectedFileChanged(s, e) {
    richEdit.PerformCallback(e.file.GetFullName());
}
protected void re_Callback(object sender, CallbackEventArgsBase e) {
    if (!String.IsNullOrEmpty(e.Parameter))
        ASPxRichEdit1.Open(Server.MapPath(e.Parameter));
}

View Example: ASPxRichEdit - How to open documents via a custom dialog with ASPxFileManager

More Examples:

You can use the JSProperties property to supply server data that should be parsed on the client. The property contains a collection of client property names and their values. Property names should have the cp prefix.

<dx:ASPxGridView ID="ASPxGridView1" runat="server" OnRowDeleted="grid_RowDeleted">
  <ClientSideEvents EndCallback="grid_EndCallback" />
</dx:ASPxGridView>
protected void grid_RowDeleted(object sender, DevExpress.Web.Data.ASPxDataDeletedEventHandler  e) {  
  ((ASPxGridView)sender).JSProperties["cpDelete"] = true;  
}  
function grid_EndCallback (s, e) {  
  if (s.cpDelete) {  
    delete s.cpDelete;  
    labelStatus.SetText("The row has been successfully deleted");  
  }
}

View Example: ASPxGridView - How to update an external control during a callback View Example: How to show the alert message if editing is not allowed

BeginCallback and EndCallback Events

DevExpress ASP.NET controls that support callbacks raise the BeginCallback and EndCallback events before and after each callback. Use an event argument’s command property to determine the action that initiated the callback.

<dx:ASPxGridView ID="Grid" runat="server" KeyFieldName="Id" ClientInstanceName="mainGrid" DataSourceID="mainSource">
    <SettingsLoadingPanel Mode="Disabled" />
    <SettingsDetail ShowDetailRow="true" />
    <Templates>
        <DetailRow>
            <dx:ASPxGridView ID="GridProducts" ClientInstanceName="gridProducts" runat="server"
                DataSourceID="productSource" KeyFieldName="Id">
                    <ClientSideEvents BeginCallback="onBeginCallback" EndCallback="onEndCallback"/>
            </dx:ASPxGridView>
        </DetailRow>
    </Templates>
</dx:ASPxGridView>
<dx:ASPxLoadingPanel ID="LoadingPanel" ClientInstanceName="loadingPanel" runat="server" Modal="true">
    <Image Url="Images/load.gif" Height="50px" Width="50px"></Image>
</dx:ASPxLoadingPanel>
function onBeginCallback(s, e) {
    loadingPanel.Show();
}
function onEndCallback(s, e) {
    loadingPanel.Hide();
    if ((e.command == "ADDNEWROW" || e.command == "UPDATEEDIT")) {
        mainGrid.Refresh();
    }
}

View Example: ASPxGridView - How to refresh a master grid when a detail grid has been updated

View Example: How to implement a custom loading panel for the ASPxCallbackPanel control

You can implement a general callback handler. The ASPxGlobalEvents is an invisible control that raises the BeginCallback and EndCallback events when any DevExpress control on a page initiates a callback.

Callback Errors

DevExpress controls include an error-handling mechanism that catches unhandled server exceptions while callbacks are processed. A control fires the client-side CallbackError event and the server-side CallbackError event. For instance, you can handle these events to display a notification or image related to the error.

For more information, see the following topic: Handle Callback Exceptions.

Disable a Control’s Callbacks

Set a control’s EnableCallBacks property to false to force the control to work in postback mode. You can wrap controls in the asp:UpdatePanel to avoid unnecessary postbacks.

<asp:ScriptManager ID="ScriptManager1" runat="server"></asp:ScriptManager>  
<asp:UpdatePanel ID="UpdatePanel1" runat="server">  
    <ContentTemplate>  
        <dx:ASPxGridView ID="ASPxGridView1" runat="server" EnableCallBacks="false" />
    </ContentTemplate>  
</asp:UpdatePanel>  

Run Demo: Grid - MS Update Panel

ASPxCallback and ASPxCallbackPanel Controls

DevExpress .NET Products include the following controls that are specially designed to work with callbacks.

ASPxCallback

ASPxCallback is a non-visual component that allows you to make a round trip to the server (send a custom callback request) and perform server-side actions. The component cannot update other controls in a callback.

Run Demo: Callback - Example View Example: How to update several controls in a single callback using the ASPxCallback control

ASPxCallbackPanel

ASPxCallbackPanel is a container area that can dynamically update its content.

Run Demo: Callback Panel - Example View Example: How to update multiple ASPxGridViews with one button and hide default update/cancel links

Simultaneous Callbacks

When you send a callback to the server, the server starts to update the page and raises page lifecycle events. At the same time, the client-side version of the page still exists and can send another callback. The server is a multi-thread system, and one of its threads may complete faster than another. For instance, if the first callback uses more data than the second callback, the second result is faster than the first. If callbacks use each other during or after a callback, the parallel (or simultaneous) callbacks can work incorrectly.

Simultaneous Callbacks Chart

To avoid such situations, it is recommended to send subsequent callbacks. They function in the following way: the first callback is sent, and the control waits until its result is available in the EndCallback event handler. When the event is raised, the second callback is sent. When the second callback ends, the third callback is sent, and so on.

Subsequent Callbacks Chart

grid1.PerformCallback();
//... 
function grid1EndCallback (s, e) { grid2.PerformCallback(); }
function grid2EndCallback (s, e) { grid3.PerformCallback(); }  

You can wrap controls in the ASPxCallbackPanel container to avoid several requests to the server to update/refresh the controls. Send a callback request to this container and update the controls in the server-side Callback event handler.

If your callbacks do not depend on each other, simultaneous callbacks work correctly.

grid1.Refresh();
grid2.Refresh();
grid3.Refresh();

View Example: How to display progress information about server-side callback processing

Session State and Simultaneous Callbacks

Simultaneous callbacks do not work if you use the session state. It blocks parallel execution and forces parallel requests to be executed one after another because access to the ASP.NET session state is exclusive per session. For this reason, the example above (How to display progress information about server-side callback processing) does not work if you use the session state.

To avoid this issue, disable the session state at either a page or project level.

Disable the Session State at a Page Level

Set the EnableSessionState property to False to disable the session state at a page level.

<%@ Page Language="C#" CodeFile="Default.aspx.cs" Inherits="_Default" EnableSessionState="False" %>

Alternatively, you can set the Page EnableSessionState property to ReadOnly. In this case, the session state is enabled but not writable.

Disable the Session State at a Project Level

Set the sessionState mode to off to disable the session state at project level.

<system.web>  
    <sessionState mode="Off"></sessionState>  
</system.web>  

When the session state is disabled, it is no longer possible to use session variables. You can use the following alternatives:

  • Application state stores variables that all users of an ASP.NET application can access.
  • Profile properties persists user values in a data store without expiring them.
  • ASP.NET caching stores values in memory that is available to all ASP.NET applications.
  • Cookies
  • The query string and fields on an HTML form that are available from an HTTP request.