Developing applications using the Web ADF - Working with AJAX capabilities of the Web ADF  

ASP.NET AJAX partial postback solutions


This document provides a detailed discussion on utilizing and extending AJAX capabilities of the Web ADF in an ASP.NET partial postback solution.  The content builds on information presented in a general discussion of AJAX and ASP.NET and an introduction to AJAX capabilities in the Web ADF .  It is recommended that you are familiar with the technologies and concepts presented in both documents before proceeding.  

Web ADF controls utilize Microsoft ASP.NET AJAX client and server libraries for all AJAX solutions.   The level to which ASP.NET AJAX is utilized depends on which postback model is leveraged in a Web page.  Client implementation for both postback models is the same - Web ADF JavaScript builds on the ASP.NET AJAX JavaScript Library to provide pure client scripting capabilities and client-server synchronization.   Server implementation determines how client-server synchronization is achieved.  For Web ADF partial postback solutions, Web ADF server controls build on ASP.NET AJAX server controls and capabilities to manage the asynchronous exchange of data via a partial page postback.   Web ADF controls will use the partial postback solution if the ASP.NET AJAX ScriptManager control is present in the same page.   With this in mind, two characteristics of ASP.NET AJAX are important to understand from the perspective of the Web ADF.  First, controls that initiate a partial postback are called triggers, must implement IPostBackEventHandler, IPostBackDataHandler or INamingContainer and must be registered with a ScriptManager.   And second, partial updates to page content can be managed using ASP.NET AJAX UpdatePanel controls, data items, or script blocks.   Note, the ScriptManager must be the first control in the page.

At a minimum, all Web ADF controls implement IPostBackEventHandler and register themselves with the current ScriptManager in the page, and thus by default can trigger a partial postback.   When a Web ADF control triggers a partial postback, Web ADF JavaScript uses the ASP.NET AJAX JavaScript Library to add an event handler.  The JavaScript event handler will listen for the page loading event for the duration of the postback.  During postback processing on the server, updates to Web ADF controls are managed by adding CallbackResults as data items to the partial postback response.  When the response is returned to the client browser, the page loading event handler processes the data items and updates Web ADF content.  Note that the logic to update Web ADF controls is included with both the Web ADF JavaScript and server control implementation.      

UpdatePanels and Web ADF controls

The ASP.NET AJAX UpdatePanel control provides a convenient means for triggering updates and updating page content via an asynchronous partial postback.  Postbacks triggered by Web controls in an UpdatePanel are asynchronous partial postbacks by default.  In addition, Web controls outside an UpdatePanel can trigger an asynchronous postback to update all content inside an UpdatePanel.    If outside an UpdatePanel, controls must explicitly register with the ScriptManager to trigger a partial postback.  The following code illustrates how this registration may occur during the page load event for an ASP.NET Button control with the id "Button1":

[C#]

protected override void OnLoad(EventArgs e)
{
  base.OnLoad(e);

  ScriptManager scriptManager1 = ScriptManager.GetCurrent(Page);
  if (scriptManager1 != null)
  {
    scriptManager1.RegisterAsyncPostBackControl(Button1);
  }
}
			
Web ADF JavaScript and server control implementations already include the logic necessary to register with the ScriptManager, trigger postbacks and update content within a partial postback solution.   As a result, Web ADF controls do not require the use of an UpdatePanel.   Web ADF controls will function within an UpdatePanel and operate as a trigger to update content in an UpdatePanel.  However, using a Web ADF control within an UpdatePanel can be very inefficient, and thus is not recommended for optimum performance.  The reason for this inefficiency is the technique used by the UpdatePanel to update content.  During a partial postback, content in an UpdatePanel is completely rerendered.   As a result, the rerendered content of a Web ADF control will be returned to the browser, which includes the HTML content, JavaScript references, and JavaScript function calls.   When outside an UpdatePanel, Web ADF controls operate with optimum efficiency.   During a partial postback, Web ADF CallbackResults are generated on the server, serialized to JSON, and registered with a ScriptManager as data items.  On the client, Web ADF specific data items are processed by Web ADF JavaScript and control content is updated.  Thus, instead of completely rerendering of a Web ADF control, very specific updates are defined within the context of ASP.NET AJAX data items.  The partial postback scenarios listed below build on this architecture to create an efficient custom solution.   

Custom Partial Postback Scenarios


There are two scenarios you may choose from to customize the Web ADF and utilize its implementation of the ASP.NET AJAX partial postback model.  In both scenarios, the Web ADF CallbackResult and CallbackResultCollection classes are integral to synchronizing changes to Web ADF controls on the server with the client browser.     


1) Web ADF components initiate the partial postback

The diagram below illustrates how a Web ADF control on the client (rendered using HTML\JavaScript in the client browser) initiates a partial postback request, a Web ADF control handles the postback on the server which generates one or more Web ADF CallbackResults, then the ASP.NET AJAX library processes the partial postback and calls a event handler added by Web ADF JavaScript to parse Web ADF CallbackResults as data items in the response.   The most important point here is that the Web ADF control that initiated the partial postback will return information that can be used to update itself and other content in the page.  The Web ADF control (the trigger in this situation) maintains a collection of Web ADF CallbackResults which will be included in the partial postback response generated by the ASP.NET AJAX ScriptManager control.  The CallbackResults collection can include CallbackResult instances from three sources.  One, the trigger itself will generate CallbackResults.  Two, custom CallbackResults can be created and added to the trigger's CallbackResults collection.  And three, the CallbackResults collections for other Web ADF controls can be copied to the trigger's CallbackResults collection.  There is one exception in this situation.  CallbackResults generated by Web ADF controls which maintain a property relationship with the trigger will be added automatically.  For example, assume a page contains a Map and Toc control where the Toc control is buddied with the Map.   At runtime, a user action on the Map causes a scale change which changes the visibility of a layer in the Map and Toc.   When the partial postback response is generated, the CallbackResults collection for the Map (the trigger in this case) will also include CallbackResults for the Toc, thus both will be included in the response.  As a developer, you did not need to copy CallbackResults from the Toc to the Map, instead the Web ADF architecture did it for you.  In general, the Web ADF control overview diagram provides a general guide to potential relationships between Web ADF controls.   Note, in this scenario, the trigger's CallbackResults collection will be registered as a data item with the ScriptManager control and processed using Web ADF JavaScript on the client for you - no explicit work is required on your part as the developer to add a client event handler or register CallbackResults as data items on the server.         



This is most common scenario for leveraging Web ADF AJAX capabilities - it includes the pattern for creating custom toolbar items that execute server-side logic using the Web ADF Toolbar architecture.  When using the Web ADF Toolbar, CallbackResults included in the partial postback are managed for you, so it's relatively easy to incorporate and execute custom code solutions in a Web ADF without explicitly creating or managing client or server side components.   Walkthrough #1 below demonstrates this scenario. 

This scenario also includes working with events on Web ADF controls.  When a Web ADF control initiates a partial postback, event handlers on Web ADF controls may generate CallbackResults to reflect changes in the control.   CallbackResults associated with the Web ADF control that initiated the partial postbackthe event occurred will automatically be included in the partial postback.  Changes to other controls or browser content can be packaged with the partial postback by adding Web ADF control CallbackResults or custom CallbackResults to the Web ADF control acting as the trigger for the postback.    Walkthrough #3 below demonstrates this scenario.      


2) Non-Web ADF components initiate the partial postback

The diagram below illustrates how to work with Web ADF controls when a partial postback is generated by non-Web ADF content in the browser.  There are three options for updating Web ADF content: UpdatePanels, data items, and dynamic script blocks.  All options are standard patterns available for ASP.NET AJAX solutions.   Web ADF controls can reside within UpdatePanels and operate successfully.  When the UpdatePanel is updated during a partial postback, it's contents are completely rerendered.  Since Web ADF controls include a JavaScript API to synchronize updates between client and server, updating Web ADF controls within an UpdatePanel is unnecessary and inefficient.  In essence, all Web ADF controls need to be updated on the client are the CallbackResults they generate on the server.  All CallbackResults are processed via the Web ADF JavaScript function ESRI.ADF.System.processCallbackResult().   CallbackResults can be inserted into the partial postback response as data items or dynamic script blocks.  

Dynamic script blocks

The ASP.NET AJAX ScriptManager permits registering a block of JavaScript, constructed on the server, to be executed on the client.  Any valid JavaScript can be included in the script block.  For Web ADF controls, the script block will merely call the ESRI.ADF.System.processCallbackResult() function and pass a collection of Web ADF CallbackResults as an input parameter.  Note, an UpdatePanel must be present in the page to use dynamic script blocks.  The UpdatePanel can be empty.

The example code below is executed on the server during a user action, such as a Button click or DropDownList item select.   The extent for a Web ADF Map control is set, which generates one or more CallbackResults, stored by the Map via the CallbackResults property.  The ToString() method on all Web ADF controls has been overridden to return the respective control's CallbackResults as a JSON serialized string (thus a call to ToString() is not necessary).  All Web ADF CallbackResults can be packaged in a single CallbackResult collection, before being converted to a string and included in the script block.  For example, if another Web ADF control changed during the postback or a custom CallbackResult was created, merely copy or add the CallbackResults to the Map.   Also, note that if you are a server control developer, and you want to create a control that works for both callbacks and partial postbacks you can check if a ScriptManager is present on the page using the GetCurrent() static method and return an instance.  If you are a page developer, you will know when a ScriptManager is on the page and you will know its id, thus interrogating the page for a ScriptManager is unnecessary. 

[C#]

. . .
string jsProcessCallbackResult = string.Format("ESRI.ADF.System.processCallbackResult('{0}');",
    Map1.CallbackResults.ToString().Replace("\\", "\\\\"));

ScriptManager.RegisterClientScriptBlock(Page, sender.GetType(), "changeextent", 
    string.Format(jsProcessCallbackResult, Map1.CallbackResults), true); 
				
[VB.NET]
. . .
Dim jsProcessCallbackResult As String = String.Format("ESRI.ADF.System.processCallbackResult('{0}');", 
    Map1.CallbackResults.ToString().Replace("\", "\\"))

ScriptManager.RegisterClientScriptBlock(Page, sender.GetType(), "changeextent", String.Format(jsProcessCallbackResult, 
    Map1.CallbackResults), True)
				

You'll notice a Replace statement to change the escape characters in ADF callback results.  This is a limitation of dynamically executed JavaScript, a characteristic f a client script block, and JSON, a format used by callback results.   It does not affect strings passed to JavaScript functions on the client, as presented in the next option, data items.  Note, the escape sequence is different for C# and VB.NET.   

This technique does present a number of benefits.  One, Web controls do not need to be completely rerendered, as is the case with an UpdatePanel.  And two, no custom client-side code is necessary to process the Web ADF CallbackResults.  One potential drawback is that all registered script blocks will persist in browser memory.   As a result, the amount of content in a script block, the number of script blocks and the expected duration of a browser session may cause browser memory to reach an unacceptable limit.   


Data items

The ASP.NET AJAX ScriptManager permits registering items of data, packaged as strings on the server and processed on the client.   The strings may be formatted using JSON.   Since Web ADF CallbackResults are formatted using JSON, they can easily be packaged as a data item and included in a partial postback response.   The ASP.NET AJAX client API (JavaScript library) includes the ability to manage event handlers on client-side JavaScript objects.  One object type, the PageRequestManager class, manages partial page updates in the browser and maintains a pageLoading event, which is raised after the response from the server to an asynchronous postback is received but before any content on the page is updated.  The pageLoading event can be used to capture data item content included in a partial postback response for use in the client browser.    These two steps and some sample code is provided below to illustrate this technique:

1) Register Web ADF CallbackResults as a data item on the server

During a partial postback on the server, register a data item.  The first parameter to the RegisterDataItem() method is the control associated with the item.  In this case, the Page is used because it provides a generic high-level control by which any Web ADF CallbackResults can be registered.  Note, that the use of the Page control is arbitrary, any unique string can be used.  The second parameter is the data item string itself.   Web ADF CallbackResults are JSON formatted strings designed to be processed by the Web ADF JavaScript function ESRI.ADF.System.processCallbackResult().  As a result, the string representation of a CallbackResults collection should be provided as the second parameter to the function.   The third parameter defines whether the data item is JSON serialized.  If the data item is a JSON serialized string (true) it's designed to be executed directly within the browser as dynamic JavaScript.  If the data item will be used as a string, such as passed as a parameter to a function, it will not be a JSON serialized string.  In this case, callback results are a JSON formatted string designed to be passed to the ESRI.ADF.System.processCallbackResult() function.             

[C#]

ScriptManager1.RegisterDataItem(Page, Map1.CallbackResults.ToString(), false);
				
2) Add a custom JavaScript function to process the CallbackResults on the client and send them to the processCallbackResults() function.  

The JavaScript content can be inserted into a page manually at design-time after the form containing the ScriptManager control is loaded or injected into the page as a startup script using server-side code.  In the example below, the JavaScript has been inserted in the body of the page, after the closing form tag.   The code will add a new event handler function for the page loading event and retrieve the data items based on a unique id (in this example, the client id of the Page).   In this case, the data item is string representing a callback result collection.  It is passed directly to the ESRI.ADF.System.processCallbackResult() function.   

[JavaScript]
<script>				
Sys.Application.add_init(onInitFunction);
    				
// Called once during application initialization
function onInitFunction()
{
   Sys.WebForms.PageRequestManager.getInstance().add_pageLoading(AsyncResponseHandler);
}

// Called whenever a response to a partial postback is processed on the client
function AsyncResponseHandler(sender, args) 
{
   var dataItems = args.get_dataItems();
   if (dataItems['__Page'] != null)
      ESRI.ADF.System.processCallbackResult(dataItems['__Page']);
}
</script>	
   
     



Utilizing data items is a common scenario for developers who want to interact with Web ADF controls when partial postbacks are triggered by non-Web ADF controls in the page.   
      

Walkthroughs

To interact with Web ADF controls and capabilities via an ASP.NET AJAX partial postback on the server, you have two options.  If the Web ADF control triggers the partial postback, use the existing Web ADF Toolbar framework or implement your own solution to manage CallbackResults via the collection on the Web ADF control trigger.  If a non-Web ADF control triggers the partial postback, you must provide a mechanism for packaging and directing CallbackResults to the appropriate Web ADF JavaScript function.   In addition, you can leverage the Web ADF to update non-Web ADF content in the page without completely rerendering the content (as in an UpdatePanel) or writing any custom JavaScript code.  
  
<walkthroughs unavailable at this time>