Click here to Skip to main content
15,891,136 members
Articles / Web Development / ASP.NET

Understanding Callback using XMLHttpRequest

Rate me:
Please Sign up or sign in to vote.
4.58/5 (11 votes)
30 Apr 2012CPOL4 min read 69.1K   8   4
Basics of callback using XMLHttpRequest object

Introduction

Async callback goes by a number of different names in the .NET community such as XMLHttpRequest, AJAX, asynchronous client script callback, to name a few. However the basic building block for callback is theXMLHttpRequest object. It is an API available in JavaScript which is used to send HTTP requests directly from the client to the server and loads the server response back to the browser. The most obvious question which comes to my mind is then what is the difference between callback and postback. Both hit the server and gets data back to the client. Callbacks differ from postback in which the former only sends relevant information back to the server and preserves the Viewstate and the form data. All the ASP.NET server page cycles occur along with client side events. This helps in loading the page faster because in the rendering phase only the relevant contentis sent to the browser. For example in AJAX, only the contents ofthe UpdatePanel are rendered in the browser.

Just to prove that ASP.NET doesundergo the complete page cycle in an AJAX application put a page directive Trace="true" All the page life cycle events does take place.

Image 1

Using the Code

Now coming back to XMLHttpRequest lets create an application which implements callback mechanisim using XMLHttp and AJAX. The application contains a grid view which displays the customer data from Adventure work database. The customer information is retrieved by clicking on the customer Id which is populated in the dropdownlist. The data in the grid view is binded to sqldatasource in the code behind file.

In an aspx page write the below javascript function.

C++
<script type ="text/javascript" >

      var xmlHttp;

      function CreateXMLHttpObject() {

          xmlHttp = new XMLHttpRequest();
      }

      function GetServerData() {

          CreateXMLHttpObject();

          if (xmlHttp == null) {
              alert('Browser does not support Ajax');
          }
          else {

              var index = document.getElementById("ddlEmployeeID");

              var id = index.options[index.selectedIndex].value;


              xmlHttp.open("GET", 'XMLHttpExample.aspx?EmployeeID=' + id, true);
              xmlHttp.onreadystatechange = ClientSideUpdate;
              xmlHttp.send(null);

          }
      }

      function ClientSideUpdate() {
          var result;

          if (xmlHttp.readyState == 4) {
             result = xmlHttp.responseText;

             document.getElementById('gvEmployeeDetails').parentNode.innerHTML = result;
         }
      }

  </script>

First step is to create an XMLHttpRequest object which is performed in the function CreateXMLHttpRequest(). If you are running the application in older version of IE(5) or firefox, the above code should be modified like the one given below

C++
function CreateXMLHttpRequest() {


    if (window.ActiveXObject) {
        xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
    }
    else {xmlHttp = new XMLHttpRequest(); }

If the browser is IE then we create a new instance of ActiveXObject or the if the browser implements the global XMLhttpRequest then the variable XMLHttp is instantiated with it.

The function GetServerData gets the Value selected from a dropdownlist using DOM and then it passes the query string to Page URL.

Open method is called for XMLHttpRequest object . The first parameter describes the HTTP Verbs (POST ,GET,PUT,DELETE etc ) and the second parameter is end point which is mapped. Here im passing the query string to the Page URL but you can even call a handler and pass a string to it and then perform some query to return data from server.

C++
xmlHttp.open("GET", "getEmployeeInfo.ashx?EmployeeID=" + id, true);

Next process is to wireup the event handler. Since it is an Async call, the user needs to get notified when the call completes. For this a method called on readystatechange is used which is mapped to handler called ClientSideUpdate. Send method invokes the end point using HTTP Verb ("GET"). The function ClientSideUpdate is a callback function which checks whether the request object is in the proper state

states:-

0- unintialized

1=loaded

2=loading

3=interactive

4=complete

If the callback is success then the response is pulled back from the XMLHttp object and gridview is populated with the reponseText.

Leaving the javascript for a moment the code inside the form tag is explained below.

<form id="form1" runat="server">
   <div>
       <select id="ddlEmployeeID" onchange ="GetServerData()">
       <option selected="selected"  >Select The Customer ID</option>
           <option >Select a value</option>
           <option value ="1" >1</option>
           <option value ="2" >2</option>
           <option value ="3" >3</option>
       </select>
       <br />
       <br />

       <asp:GridView runat="server" ID="gvEmployeeDetails" AutoGenerateColumns ="false"  >
       <Columns >
       <asp:BoundField DataField="FirstName" HeaderText ="First Name" />
       <asp:BoundField DataField="MiddleName" HeaderText ="Middle Name" />
       <asp:BoundField DataField="LastName" HeaderText ="Last Name" />
       </Columns>
       </asp:GridView>

       <asp:SqlDataSource runat="server" ID="AdventureWorksDataSource"
        ConnectionString="Data source=PRAVEEN-HP\PRAVEEN;Initial Catalog=AdventureWorks2008R2;Integrated Security=SSPI "
        SelectCommand="Select FirstName,MiddleName,LastName from [Person].[Person] where BusinessEntityID=@EmployeeID"
        DataSourceMode="DataReader">

        <SelectParameters >
        <asp:QueryStringParameter DbType="Int32" Name="EmployeeID" QueryStringField="CustomerID" DefaultValue ="1" />
        </SelectParameters>

       </asp:SqlDataSource>
   </div>
   </form>

The database used here is AdventureWorks2008R2 and is used to retrieve employee details from the table Person. I have hard coded the dropdownlist with employee ID values. Inside the SqlDataSource querystringparameter is used which passes the value of EmployeeID to where clause in the SelectCommand.

Now the javascript function GetServerData is called in the dropdownlist event handler. So whenever the user selects the value the function will be triggered.

Grid view is binded to sqldatasource in the code behind file.

public partial class XMLHttpExample : System.Web.UI.Page
  {
      List<Employee> _employee = null;
      protected void Page_Load(object sender, EventArgs e)
      {
          string _employeeID = Request.QueryString["EmployeeID"];

          if (_employeeID != null)
          {
              AdventureWorksDataSource.SelectParameters.Add("@EmployeeID", _employeeID);

              Response.ClearContent();
              Response.ContentType = "";


              gvEmployeeDetails.DataSource = AdventureWorksDataSource;
              gvEmployeeDetails.DataBind();

              StringWriter sw = new StringWriter();
              HtmlTextWriter htw = new HtmlTextWriter(sw);
              gvEmployeeDetails.RenderControl(htw);
              Response.Write(sw.ToString());
              Response.End();

          }

          else
          {
              _employee = new List<Employee>();
              _employee .Add (new Employee(){
              FirstName ="Praveen",
              LastName ="Kumar",
              MiddleName  ="Nothing"
              });

              gvEmployeeDetails.DataSource = _employee;
              gvEmployeeDetails.DataBind();

          }
      }
      public override void VerifyRenderingInServerForm(Control control)
      {
          return;
      }
  }

  public class Employee
  {
      public string FirstName { get; set; }
      public string LastName { get; set; }
      public string MiddleName { get; set; }
  }

The code is quite self explanatory. A class Employee is created with 3 properties. In the Page load event querystring is retrieved and then passed in as a parameter to the sqldatasource and finally it is binded to the gridview .Response.Write is used to inject the string to innerHtml property of the gridview.

C++
document.getElementById('gvEmployeeDetails').parentNode.innerHTML = result;

The explanantion seems to be quite lengthy but its actually important to understand the concept of XMLHttpRequest in order to get familar with Ajax.

Now the same implementation can be done using Ajax extentions (Update Panel).

Update Panel enables asynchronous postbacks via Partial Page rendering because it is only going to repopulate the page not the complete page in a traditional Postback. The best part is it gives us Async callback or Ajax enabled pages without custom client script. The code for the update panel is:

<asp:UpdatePanel ID="UpdatePanel1" runat="server" UpdateMode="Conditional" >
     <ContentTemplate >
         <asp:DropDownList runat="server" ID="ddlEmployeeID"  AutoPostBack="true"
             OnSelectedIndexChanged ="ddlEmployeeID_SelectedIndexChanged"  >
         <asp:ListItem Text="Select a value" />
             <asp:ListItem Text="1" Value ="1" />
             <asp:ListItem Text="2" Value ="2" />
             <asp:ListItem Text="3" Value ="3" />
         </asp:DropDownList>
         <br />
         <br />

     <asp:GridView runat="server" ID="gvEmployeeDetails1" AutoGenerateColumns ="false"  >
       <Columns >
       <asp:BoundField DataField="FirstName" HeaderText ="First Name" />
       <asp:BoundField DataField="MiddleName" HeaderText ="Middle Name" />
       <asp:BoundField DataField="LastName" HeaderText ="Last Name" />
       </Columns>
       </asp:GridView>

       <asp:SqlDataSource runat="server" ID="AdventureWorksDataSource"
        ConnectionString="Data source=PRAVEEN-HP\PRAVEEN;Initial Catalog=AdventureWorks2008R2;Integrated Security=SSPI "
        SelectCommand="Select FirstName,MiddleName,LastName from [Person].[Person] where BusinessEntityID=@EmployeeID"
        DataSourceMode="DataReader">

        <SelectParameters >
        <asp:QueryStringParameter DbType="Int32" Name="EmployeeID" QueryStringField="CustomerID" DefaultValue ="1" />
        </SelectParameters>

       </asp:SqlDataSource>
     </ContentTemplate>
     <Triggers >
     <asp:AsyncPostBackTrigger ControlID ="ddlEmployeeID" EventName="SelectedIndexChanged" />
     </Triggers>
       </asp:UpdatePanel>

The same controls used with the 1st application is now wrapped inside the update panel. All the javascript code is placed in DLL called AjaxControlToolkit. So very rarely we will use javascript library for server side interaction for Async callback (Ajax). An event handler is added to dropdownlist

protected void ddlEmployeeID_SelectedIndexChanged(object sender, EventArgs e)
       {
           string _employeeID = ddlEmployeeID.SelectedValue;

           AdventureWorksDataSource.SelectParameters.Add("@EmployeeID", _employeeID);
           gvEmployeeDetails1.DataSource = AdventureWorksDataSource;
           gvEmployeeDetails1.DataBind();
       }

Huh now this completes the full cycle. XMLHttpRequest is just a way of passing Asynchronous message over HTTP and opens a whole new way of how the web page interacts with the clients. The website which makes excellent use of ajax is Google maps.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
India India
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
QuestionMy Vote of 4 Pin
BharatRamV18-Mar-14 0:30
professionalBharatRamV18-Mar-14 0:30 
GeneralMy vote of 2 Pin
aditya_bokade11-Jan-14 1:31
aditya_bokade11-Jan-14 1:31 
GeneralMy Vote Of 4 Pin
Alireza_13621-May-13 5:00
Alireza_13621-May-13 5:00 
GeneralMy vote of 5 Pin
umeshsaini10-Nov-12 19:03
umeshsaini10-Nov-12 19:03 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.