Client Callbacks


Many Web applications today are leveraging asynchronous JavaScript calls over HTTP in the client to provide a more interactive user interface experience. Instead of issuing a standard POST request with an HTML form, these applications leverage client-side events and the XMLHttpRequest object available in all modern-day browsers to issue HTTP requests back to the server without issuing a full postback. This type of request is much more innocuous to the user as there is no visible impact on the page except for the additional data displayed, and when done well, the Web application feels more like a responsive desktop application rather than a typical Web application. This technique has other advantages too, including the fact that the page will maintain its scroll and cursor positions without having to resort to server-side tricks to reset them as desired with each request.

Client Callback Framework

There is a lot of work involved with using asynchronous callbacks by hand, including setting up the XMLHttpRequest object, preparing and formatting the request, and building the handler for the response. If you want your client code to be browser independent as well, the work increases even more. ASP.NET 2.0 introduces a framework that relieves you of much of the grunt work for performing client callbacks, and has a collection of client-side JavaScript routines and a server-side interface for simple interaction, complete with browser independence. You are left to write some client-side JavaScript to issue the callback as well as a handler for processing the result, and then implementing a server-side callback method that returns the data you need. Typically in your client-side handler, you would then manipulate the client-side document object model (DOM) to display the results of your callback in some fashion.

Figure 8-4 shows a typical interaction between the client and server for a page that is using client callbacks to retrieve data instead of the typical HTML POST. Note that the initial request is a standard GET request to retrieve the initial page, and that the subsequent POST request is initiated by a client-side event (onclick on the lookup symbol input element). The call back to the server is handled by a fresh instance of the Page class, but the Page is only executed through the Load event, at which point the Callback event is raised and the server-side callback method is executed to return the requested data.

Figure 8-4. Client callback architecture


There are two core elements you need to put in place to use the callback architecture in ASP.NET 2.0: you need to implement the ICallbackEventHandler interface and call the ClientScript.GetCallbackEventReference from client-side JavaScript. The data passed from client to server and back again is always just a string, so it is up to you to decide what format that string should take and how much effort you want to put into formatting and parsing it. The ICallbackEventHandler interface, shown in Listing 8-23, defines two methods that your control (or page) must implement.

Listing 8-23. The ICallbackEventHandler interface

public interface ICallbackEventHandler {   string GetCallbackResult();   void RaiseCallbackEvent(string eventArgument); } 

The RaiseCallbackEvent method will be called first with the string parameter passed by the client callback method, and the GetCallbackResult method will be called next, which is where you return the string of data for your client-side script to process. This interface defines two methods instead of just one to perform the callback to support asynchronous processing scenarios. This interface can be implemented for an entire page, or if you are building a custom control or user control and would like to leverage client callbacks, you can implement it at the control level as well. Several of the built-in Web controls implement this interface to support on-demand population of data through client callbacks, including the TreeView, GridView, and DetailsView controls.

As an example of using client callbacks, Listings 8-24 and 8-25 show the implementation of a page that lets a user check a stock quote, and that maintains a list of each quote requested in a multiline text box on the page. The request to get a quote is performed using a client callback instead of a traditional HTML POST. In this page, the server-side callback method, GetCallbackResult, returns a simple string indicating the value of the requested stock symbol. The client-side work is done in a pair of methods registered using the ClientScript.RegisterClientScriptBlock method from within the Init event handler. The first JavaScript method, RetrieveStockQuoteFromServer, retrieves the value from the input element where the user types the symbol to be requested and stores it in a local variable, symbolInput. Next, it invokes the callback method retrieved by calling GetCallbackEventReference of the ClientScript class, passing in the string value (the symbol) and the name of the callback method (StockQuoteFromServer). Finally, the method that processes the result of the callback, StockQuoteFromServer, takes a result string and adds it to the list of strings in the multiline text box.

Listing 8-24. Callback.aspxusing client callbacks

<%@ Page Language="C#" AutoEventWireup="true"                  CodeFile="Callback.aspx.cs" Inherits="Callback" %> <html xmlns="http://www.w3.org/1999/xhtml" > <head runat="server" /> <body>     <form  runat="server">     <div>     Enter symbol:         <asp:TextBox  runat="server" /><br />         <input  name="_lookupSymbolInput"                type="button" value="Lookup symbol"                onclick="RetrieveStockQuoteFromServer()" /><br />         <asp:TextBox  runat="server" Rows="4"                      TextMode="MultiLine" Width="75%" /><br />     </div>     </form> </body> </html> 

Listing 8-25. Callback.aspx.csusing client callbacks

public partial class Callback : Page, ICallbackEventHandler {   public string GetCallbackResult()   {     return string.Format("The value of {0} at {1} is {2}", _arg,                     DateTime.Now.ToString(),                     new Random(Environment.TickCount).Next(0, 120));   }   private string _arg;   public void RaiseCallbackEvent(string eventArgument)   {     _arg = eventArgument;   }   protected void Page_Init(object sender, EventArgs e)   {   string callbackEventRef =        ClientScript.GetCallbackEventReference(this,                       "symbolInput.value", "StockQuoteFromServer", "");     string callbackMethod =             "function RetrieveStockQuoteFromServer() { \r\n" +               "var symbolInput = document.getElementById('"                             + _symbolTextBox.ClientID +                   "');" + callbackEventRef +               ";\r\n}\r\n";     string processResultMethod =              "function StockQuoteFromServer(result, context) { \r\n"+                "var resultTextBox = document.getElementById('" +                _resultTextBox.ClientID + "');\r\n" +     "resultTextBox.value = resultTextBox.value + '--' + result;\r\n" +                "}\r\n";         ClientScript.RegisterClientScriptBlock(this.GetType(),                "CallbackFunctions",                 callbackMethod + processResultMethod, true);     } } 

On-Demand TreeView Node Population

As mentioned earlier, several of the built-in Web controls support client callbacks for on-demand population of their data. For example, the TreeView control lets you specify an attribute on individual nodes of the tree called PopulateOnDemand, which will cause the TreeView to issue a callback to retrieve the next child node when it is expanded. Once you mark one or more nodes in a TreeView to be populated on demand, you then must define a handler for the TreeNodePopulate event, which will be called every time an on-demand node is expanded. Listing 8-26 shows a simple example of creating a TreeView that populates its nodes on demand, in this case to enumerate the Fibonacci number sequence. Figure 8-5 shows what the TreeView looks like once it has been expanded several times.

Listing 8-26. On-demand TreeView displaying Fibonacci numbers

<%@ Page Language="C#" Title="Fibonacci Tree On Demand" %> <script runat="server"> protected void PopulateNode(Object source, TreeNodeEventArgs e) {   // The text of a node in this tree is the current Fibonacci number   // The value of a node in this tree is the *next* Fibonacci number   double nodeText = double.Parse(e.Node.Text);   double nodeValue = double.Parse(e.Node.Value);   // Create new tree node with new value and set to populate on demand   TreeNode newNode = new TreeNode(nodeValue.ToString(),                                   (nodeText + nodeValue).ToString());   newNode.PopulateOnDemand = true;   // Insert new node as child   e.Node.ChildNodes.Add(newNode); } </script> <html xmlns="http://www.w3.org/1999/xhtml" > <head runat="server" /> <body>   <form  runat="server">   <div>   <h3>Fibonacci Tree</h3>     <asp:TreeView                    OnTreeNodePopulate="PopulateNode"                   runat="server" ExpandDepth="1">       <Nodes>         <asp:TreeNode Text="1" Value="1">           <asp:TreeNode PopulateOnDemand="true" Text="1" Value="2" />         </asp:TreeNode>       </Nodes>     </asp:TreeView>     </div>     </form> </body> </html> 

Figure 8-5. On-demand TreeView displaying numbers from the Fibonacci sequence


Atlas

It turns out that client callbacks were just the tip of the iceberg for the supporting AJAX-style application development with ASP.NET 2.0. After the 2.0 framework was released, the ASP.NET team set to work on building Atlas, a rich framework for building AJAX-enabled Web applications with ASP.NET. This new Web development framework provides both client-side and server-side components for closing the gap between Web and desktop user interfaces. Atlas' browser-neutral client script library is easily integrated with existing Web applications (including ASP.NET 1.x and non-.NET sites), improving response times and enhancing UIs with DHTML and JavaScript features that in the past would have taken enormous development efforts and extensive client-side knowledge. ASP.NET 2.0 applications can take advantage of Atlas' server-side features to further enhance their UIs, often through simple markup, without having to resort to adding their own client-side JavaScript at all. The scope of Atlas is too large to do it justice in this book, and as of this writing, it is still under development. To get the latest information and resources on developing with Atlas, visit http://atlas.asp.net.




Essential ASP. NET 2.0
Essential ASP.NET 2.0
ISBN: 0321237706
EAN: 2147483647
Year: 2006
Pages: 104

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net