AspAlliance.com LogoASPAlliance: Articles, reviews, and samples for .NET Developers
URL:
http://aspalliance.com/articleViewer.aspx?aId=1573&pId=-1
Working with Callback and Control Rendering
page
by Muhammad ADnan Amanullah
Feedback
Average Rating: 
Views (Total / Last 10 Days): 41238/ 59

Introduction

In my previous article, I wrote about Callback and JSON based JavaScript serialization which you can find here. Callback doesn't cause postback and page rendering, neither full nor even partial. With it we can communicate with the server (IIS) and our server side code runs there successfully and could rebind our controls like DropDownList, GridView, ListView, DataList, Repeater, or any server side control to which you assign data. The problem is when the page won't render, its controls won't render, and if controls won't render then changes won't reflect. When changes don't reflect there won't be anything at the front end to show on the webpage.

This article is mainly about callback and rendering controls but through this tutorial you can also learn many other things; how postbacks work, how rendering works, how to dynamically create server-side controls, how to create DataTables dynamically in memory to bind with, how to get server-side controls during client-side execution and set their properties, and how to register client-side events of server side control from the server-side code.

Important Terms

First of all, I would like to briefly describe some terms of which I believe every web developer should be aware.

Postback

A postback is a mechanism of communication between client-side (browser) and server-side (IIS). Through a postback all contents of page/form(s) are sent to the server from client for processing. After following the page life cycle, all server-side contents get render into client-side code and the client (browser) displays the content. Callback is another form of communication between server and client. Callback doesn’t follow the page life cycle which is followed by standard postback, and it doesn't even cause rendering.

Rendering

Rendering is the process of converting server-side code/content into client-side code/content so the client (browser) can understand the code and could display the output. Browsers can understand, or you may say decode, code of client-side languages and scripts like HTML, DHTML, XHTML, JavaScript, VbScript, etc.

If rendering doesn't happen then changes won’t be reflected at client-side. Ajax leverages partial page postbacks automatically whereas callback doesn't, so programmer needs to perform that task manually.

The ASP.NET team has created a RenderControl method which is applied to the base control. By using that method we can render our controls very easily.

Callback

Callback is a lightweight process. It uses the well known XMLHTTP object internally to call server side methods. It doesn't cause page postback so doesn’t cause page rendering, so if we want to show output at client side, we need to make output html ourselves and render controls manually.

ICallbackEventHandler

ICallback is implemented in ASP.NET by using the ICallbackEventHandler interface, which has two methods, one of them used to be called from JavaScript (client-side code) and the other one returned results asynchronously back to the JavaScript function.

We just need to perform some action through server-side code at server-side and need to return results, but the results could be an instance or object of a class which might not be easy for JavaScript code to handle, so here we prefer JSON which stands for JavaScript Object Notation.

Real Time Scenario with implementation

Suppose we have categories, subcategories, products data, and we need to populate categories and subcategories which depend upon categories, and the data would be populated in two different DropDownLists. For products data which contains multiple columns so we need to show that data in tabular format so I would prefer GridView control.

So the situation would be load/populate categories on Page_Load and load/populate subcategories on the basis of selected category using callback and finally load products into Gridview on the basis of selected subcategory.

Before starting coding, I would like to write the Pseudo code for better understanding.

Steps

1.    Create Server side controls e.g. DropDownLists and GridView

2.    Load Categories on Page load

3.    Implement ICallbackEventHandler interface

4.    Create subcategories data in server memory to bind to Subcategory DropDownLists.

5.    Render control (subcategory DropDownLists) and show output.

6.    Create products data in server memory to bind to Products GridView.

7.    Render Control (products GridView) and return rendered contents to client side to show

8.    Set innerHTML of each control by rendered contents

Create DropDownLists and GridView Controls

Listing 1

<b>Categories:</b>
<br />
<asp:DropDownList ID="ddlCategories" runat="server" Width="100" onchange="CallSrv(this);">
</asp:DropDownList>
<br />
<b>Subcategories</b>:
<div id="ddlSubcategories">
</div>          
<b>Products:</b>
<div id="grvProducts">        
</div>
Callback Server side code

Let's implement the ICallbackEventHandler to call server side methods asynchronously step by step

Implement Server Side (C#) Page/Control class by System.Web.UI.ICallbackEventHandler

Following are definition of two methods which needs to implement:

RaiseCallbackEvent method invoke by JavaScript function

Listing 2

public void RaiseCallbackEvent(string eventArgument)
{
  string[]commands = eventArgument.Split("," .ToCharArray());
  if (commands[0].Equals("LoadSubCategory"))
  {
    DropDownList ddlSubcategories = new DropDownList();
    switch (commands[1])
    {
      case "Autos":
        ddlSubcategories.Items.Add("Cars");
        ddlSubcategories.Items.Add("Bikes");
        break;
      case "Electronics":
        ddlSubcategories.Items.Add("Computers");
        ddlSubcategories.Items.Add("TV");
        break;
    }
    ddlSubcategories.Attributes.Add("onchange""CallSrv(this);");
    System.Text.StringBuilder sb = new System.Text.StringBuilder();
    System.IO.StringWriter sw = new System.IO.StringWriter(sb);
    HtmlTextWriter htw = new HtmlTextWriter(sw);
 
    ddlSubcategories.RenderControl(htw);
    this.RenderedOutput = "LoadSubCategory," + sb.ToString();
  }
  else if (commands[0].Equals("LoadProducts"))
  {
    DataTable dtProducts = new DataTable();
    dtProducts.Columns.Add("ProductName");
    dtProducts.Columns.Add("ProductDescription");
    dtProducts.Columns.Add("ProductPrice");
    DataRow drProduct;
    switch (commands[1])
    {
      case "Cars":
        drProduct = dtProducts.NewRow();
        drProduct["ProductName"= "Honda";
        drProduct["ProductDescription"= "2000 CC";
        drProduct["ProductPrice"= "$1000";
        dtProducts.Rows.Add(drProduct);
        drProduct = dtProducts.NewRow();
        drProduct["ProductName"= "Toyota";
        drProduct["ProductDescription"= "1800 CC";
        drProduct["ProductPrice"= "$800";
        dtProducts.Rows.Add(drProduct);
        break;
      case "Bikes":
        drProduct = dtProducts.NewRow();
        drProduct["ProductName"= "Pak Hero";
        drProduct["ProductDescription"= "125 CC";
        drProduct["ProductPrice"= "$100";
        dtProducts.Rows.Add(drProduct);
        drProduct = dtProducts.NewRow();
        drProduct["ProductName"= "Honda";
        drProduct["ProductDescription"= "250 CC";
        drProduct["ProductPrice"= "$150";
        dtProducts.Rows.Add(drProduct);
        break;
      case "Computers":
        drProduct = dtProducts.NewRow();
        drProduct["ProductName"= "Dell";
        drProduct["ProductDescription"= "P4 Centrino";
        drProduct["ProductPrice"= "$400";
        dtProducts.Rows.Add(drProduct);
        drProduct = dtProducts.NewRow();
        drProduct["ProductName"= "IBM";
        drProduct["ProductDescription"= "P4 Think PAD";
        drProduct["ProductPrice"= "$350";
        dtProducts.Rows.Add(drProduct);
        break;
      case "TV":
        drProduct = dtProducts.NewRow();
        drProduct["ProductName"= "Sony";
        drProduct["ProductDescription"= "Plasma";
        drProduct["ProductPrice"= "$600";
        dtProducts.Rows.Add(drProduct);
        drProduct = dtProducts.NewRow();
        drProduct["ProductName"= "Philips";
        drProduct["ProductDescription"= "Projection";
        drProduct["ProductPrice"= "$550";
        dtProducts.Rows.Add(drProduct);
        break;
    }
    GridView grvProducts = new GridView();
    grvProducts.DataSource = dtProducts;
    grvProducts.DataBind();
 
    System.Text.StringBuilder sb = new System.Text.StringBuilder();
    System.IO.StringWriter sw = new System.IO.StringWriter(sb);
    HtmlTextWriter htw = new HtmlTextWriter(sw);
    grvProducts.RenderControl(htw);
    this.RenderedOutput = "LoadProducts," + sb.ToString();
  }
}
 
public string GetCallbackResult()
{
  return RenderedOutput;
}

In the Page_Load or Page_Init events

Following statements are used to register client side methods.

CallServer(arg, context) as name implies would use to call/raise server side method which was RaiseCallbackEvent string eventArgument)

ReceiveServerData(arg, context) would use to get result through arg parameter by GetCallbackResult()

Listing 3

//Register Client Script for Callback and populate categories
protected void Page_Load(object sender, EventArgs e)
{
  ClientScriptManager scriptMgr = Page.ClientScript;
  String cbReference = scriptMgr.GetCallbackEventReference(this"arg",
    "ReceiveServerData", "");
  String callbackScript = "function CallServer(arg, context) {" + cbReference +
    "; }";
  cm.RegisterClientScriptBlock(this.GetType(), "CallServer", callbackScript,
    true);
 
  if (!Page.IsPostBack)
  {
    //Load Products Data
    this.ddlCategories.Items.Add("Select");
    this.ddlCategories.Items.Add("Autos");
    this.ddlCategories.Items.Add("Electronics");
  }
}
Callback client side code

Listing 4

<script language = "JavaScript" type = "text/JavaScript">
function ReceiveServerData(arg, context)
{
  var cmd_content = arg.split(',');
  if (cmd_content[0] == 'LoadSubCategory')
  {
    document.getElementById('ddlSubcategories').innerHTML = cmd_content[1];
  }
  else
  {
    document.getElementById('grvProducts').innerHTML = cmd_content[1];
  }
}
function CallSrv(ddl)
{
 
  if (ddl.id == 'ddlCategories')
  {
    if (ddl.value != 'Select')
    {
      CallServer('LoadSubCategory' + ',' + ddl.value, '');
    }
  }
  else
  {
    CallServer('LoadProducts' + ',' + ddl.value, '');
  }
}
</script>

That's it. These are the steps which you need to use to call and get result from server side code using ICallback.

Asynchronously output would be within a millisecond and without Postback

Figure 1

Downloads
Conclusion

Callback is a lightweight technique used to call server side methods asynchronously from JavaScript without any postback and reloading/rendering of unnecessary parts of a page and unnecessary code.

So we can use that when we need to perform any operations at the backend on the server like updating records in database. You don't need to send all your contents of page in a request and make that object heavyweight which could cause slow performance.


Product Spotlight
Product Spotlight 

©Copyright 1998-2024 ASPAlliance.com  |  Page Processed at 2024-04-23 10:18:30 AM  AspAlliance Recent Articles RSS Feed
About ASPAlliance | Newsgroups | Advertise | Authors | Email Lists | Feedback | Link To Us | Privacy | Search