ASP.NET 2.0 Client-Side Features: Bring Server-Side Power to the Client

CodeGuru content and product recommendations are editorially independent. We may make money when you click on links to our partners. Learn More.

In addition to providing a number of new features on the server side, ASP.NET 2.0 also provides a number of improvements on the client side; these increase Web developers’ productivity. These feature improvements include script callbacks, cross-page postbacks, setting focus in a page, client-side button click events, and maintaining scrollbar position in the page. This article explores ASP.NET 2.0’s client-side features in detail, providing examples of how to use them in your Web applications.

Script Callback

Probably the most interesting ASP.NET 2.0 client-side feature is script callback, which allows you to make a server-side call from the client side without posting back to the server. Think of all the times when you wanted to retrieve information from the server after the user had performed some action, like entering a product number. To accomplish this, you traditionally posted the current page to the server, retrieved the product information, and refreshed the page with the information retrieved from the server. Although very common, this method is inefficient: the Web page refreshes, re-rendering an entire page of content, even though only a small percentage of the page has actually changed. You probably have encountered this inefficiency when searching a catalog or a search engine. The delays and waste of resources can be significant.

However, if you could accomplish the same functionality without refreshing the browser page, you would greatly enhance the user experience. This is precisely where script callback comes into play. It provides a simple and straightforward way to execute remote logic directly from the client side.

Script Callback Architecture

Script callback provides a way to execute a piece of code on the server without leaving the current page or posting back to the server. Before looking at an example, take a look at the architecture of the script callback. Figure 1 shows how script callback works.

Figure 1. How Script Callback Works

Performing a client callback involves the following steps:

  1. Call the page’s GetCallbackEventReference method to get the name of a client-side function that will be called to initiate a callback. (Note that the GetCallbackEventReference method is declared in the ICallbackEventHandler namespace and you must explicitly implement that interface by adding the Implements directive at the top of the page.) Then, that function is called from the client side (obviously using a client-side script).
  2. That function prompts ASP.NET’s callback manager, which is itself implemented in client-side script, to launch an XMLHTTP callback to the server.
  3. On the server side, ASP.NET receives the call and invokes the page’s ICallbackEventHandler.RaiseCallbackEvent() method, which processes and returns the callback.
  4. The callback manager is notified that the execution has completed.
  5. The callback manager notifies the caller that the call completed by calling a client-side notification function (provided by the caller when it initiated the call).

To demonstrate the script callback feature, this article provides an example wherein you retrieve the details of a product based on the product ID entered in the Web page. You will learn how to retrieve the product details without posting the page back to the server.

Implement Script Callback in an ASP.NET 2.0 Page

Start by creating a Web site named ClientFeatures. Next, add a new Web form named ScriptCallback.aspx to it. Modify the code in the ScriptCallback.aspx file to read as follows:

<%@ page language="C#" %>
<%@ Import Namespace="System.Data" %>
<%@ Import Namespace="System.Data.SqlClient" %>
<%@ Import Namespace="System.Xml" %>
<%@ Import Namespace="System.Web.Configuration" %>
<%@ implements interface="System.Web.UI.ICallbackEventHandler" %>

<script runat="server">

public string RaiseCallbackEvent(string eventArgs)
{
   try
   {
      int value = Int32.Parse(eventArgs);
      return GetProductDetails(value);
   }
   catch (Exception ex)
   {
      throw new ApplicationException
         ("An Error has occured during the processing " +
          " of your request. Error is :" + ex.Message);
   }
}

public string GetProductDetails(int productID)
{
   string connString =
      WebConfigurationManager.ConnectionStrings["Northwind"].
      ConnectionString;
   using (SqlConnection sqlConnection = new SqlConnection(connString))
   {
      try
      {
         DataSet productsDataset = new DataSet("ProductsRoot");
         //Pass in the name of the stored procedure to be
         //executed and the SqlConnection object as the argument
         SqlDataAdapter adapter = new SqlDataAdapter();
         SqlCommand command = new SqlCommand
         ("Select ProductID,ProductName,QuantityPerUnit, " +
         "UnitPrice from Products Where ProductID =" +
         productID.ToString(), sqlConnection);
         //Set the SqlCommand object properties
         command.CommandType = CommandType.Text;
         adapter.SelectCommand = command;
         //Fill the Dataset with the return value from the
         //stored procedure
         adapter.Fill(productsDataset,"Products" );
         return productsDataset.GetXml();

      }
      catch (Exception ex)
      {
         throw ex;
      }
   }
}


public void Page_Load(object sender, EventArgs e)
{
   if (!Request.Browser.SupportsCallback)
      throw new ApplicationException
      ("This browser doesn't support Client callbacks.");
   string src = Page.ClientScript.GetCallbackEventReference(this, "arg",
      "DisplayResultsCallback", "ctx", "DisplayErrorCallback",
      false);
   string mainSrc = @"function GetProductDetailsUsingPostback(arg, ctx)
      { " + src + "; }";
   Page.ClientScript.RegisterClientScriptBlock(this.GetType(),
      "GetProductDetailsUsingPostback", mainSrc, true);
}

</script>
<html>
<head id="Head1" runat="server">
<title>
   Retrieving XML Dynamically using ASP.NET 2.0 Script Callback
</title>
<script language="javascript">

function GetProductDetails()
{
   var n = document.forms[0].txtProductID.value;
   GetProductDetailsUsingPostback(n, "txtNumber");
}

function DisplayResultsCallback( result, context )
{
   var strXML,objXMLNode,objXMLDoc,objProduct,strHTML;
   objXMLDoc = new ActiveXObject("Microsoft.XMLDOM");
   //Load the returned XML string into XMLDOM Object
   objXMLDoc.loadXML(result);
   //Get reference to the Products Node
   objProduct = objXMLDoc.selectSingleNode("ProductsRoot").
   selectSingleNode("Products");
   //Check if a valid product reference is returned from the server
   strHTML = "<font color='#0000FF'>";
   if (objProduct != null)
   {
      //Dynamically generate HTML and append the contents to a
      //string variable
      strHTML += "<br><br>Product ID :<b>" +
         objProduct.selectSingleNode("ProductID").text +
         "</b><br><br>";
      strHTML += "Product Name :<b>" +
         objProduct.selectSingleNode("ProductName").text +
         "</b><br><br>";
      strHTML += "Quantity Per Unit :<b>" +
         objProduct.selectSingleNode("QuantityPerUnit").text +
         "</b><br><br>";
      strHTML += "Unit Price :<b>" +
         objProduct.selectSingleNode("UnitPrice").text +
         "</b><br><br>";
   }
   else
   {
      strHTML += "<br><br><b>Product not found</b>";
   }
   strHTML += "</font>"
   //Assign the dynamically generated HTML into the div tag
   divContents.innerHTML = strHTML;
}

function DisplayErrorCallback( error, context )
{
   alert("Product Query Failed. " + error);
}
</script>
</head>
<body>
<form id="Form1" runat="server">
<font color="#800080"><H1>Product Details</H1></font>
<br><br>
<P align="left"><font color="#800080">
<b>Enter the Product ID:</b></font>
     
<INPUT id="txtProductID" name="txtProductID"
       style="LEFT: 149px; TOP: 72px">
<INPUT id="btnGetProduct" type="button" value="Get Product Details"
       name="btnGetProduct" onclick="GetProductDetails()">
</P><P></P>
<div id="divContents">
</div>
<P></P>
</form>
</body>
</html>

More by Author

Get the Free Newsletter!

Subscribe to Developer Insider for top news, trends & analysis

Must Read