Remote scripting technology has been around for many years. We have seen the use of this under many names like AJAX, MajicAJAX and Callbacks. In this article I will demonstrate a new feature that is included in ASP.NET 2.0. This feature is known as Client CallBacks. Client callbacks allows you to call the server side methods without requiring a postback. This means that you can send a request from the user and fetch and display the data from the database without requiring a postback. This great feature improves the user experience as the user no longer experience the page flicker caused by the postback.

Introduction:

Remote scripting technology has been around for many years. We have seen the use of this under many names like AJAX, MajicAJAX and Callbacks. In this article I will demonstrate a new feature that is included in ASP.NET 2.0. This feature is known as Client CallBacks. Client callbacks allows you to call the server side methods without requiring a postback. This means that you can send a request from the user and fetch and display the data from the database without requiring a postback. This great feature improves the user experience as the user no longer experience the page flicker caused by the postback.

Layout of the Page:

The layout of the page is very simple. There is a TextBox on the page which allows the user to enter the categoryID. When the user clicks the "Submit" button the request is sent to the server and populates the dynamically created GridView with data. I am using the Northwind database Products table in this article.

Implementing the ICallbackEventHandler:

In order to work with the Client Callbacks your page must implement the ICallbackEventHandler. Take a look at the code below which shows that how you can implement the ICallbackEventHandler.

public partial class LearningClientCallBacks : System.Web.UI.Page, ICallbackEventHandler

{

#region ICallbackEventHandler Members

public string GetCallbackResult() {

}

public void RaiseCallbackEvent(string eventArgument)

{

}

#endregion

 

At this time we have implemented the ICallbackEventHandler. Now, let's see how we can register the scripts so they can call the server method and get the data back to the client.

Setting Up the Callback Function:

The next step is to set up the callback function which will receive the data returned from the server. You can do this in the Page_Load method of the Page class. Take a look at the code below.

protected void Page_Load(object sender, EventArgs e)

{

string sbReference = ClientScript.GetCallbackEventReference(this, "arg", "ReceiveServerData", "context");

string cbScript = String.Empty;

// check if the script is already registered or not

if (!ClientScript.IsClientScriptBlockRegistered("CallServer"))

{

cbScript = @" function CallServer(arg,context) { " + sbReference + "}";

ClientScript.RegisterClientScriptBlock(this.GetType(), "CallServer", cbScript, true);

}

}

The ClientScript.GetCallbackEventReference is used to mark a JavaScript function which will receive the data or the result from the server. The ClientScript.IsClientScriptBlockRegistered is used to check that if the script has already been registered or not. If the script is not registered then the function CallServer is registered using the ClientScript.RegisterClientScriptBlock method. The CallServer method takes two arguments which is the argument and the context.  

After registering the ClientScript you need to implement the GetCallback and RaiseCallback events. The RaiseCallback event is fired whenever you make a call to the CallServer method which we have injected into the page inside the Page_Load event.

// protected variable

protected string returnValue;

public void RaiseCallbackEvent(string eventArgument)

{

if (!String.IsNullOrEmpty(eventArgument))

{

returnValue = eventArgument;

}

else

{

// Set a flag so that the GetCallbackResult is not called.

}

}

The RaiseCallbackEvent takes a single parameter which is the eventArgument. In this case we will be passing the categoryID as the eventArgument so that we can get all the products from the Products table based on the categoryID.

The next event that is fired is the GetCallbackResult which is the method that will return the data to the client. The method returns only as type "String". This is the limitation of using the Client Callbacks in ASP.NET 2.0. Hence, if you like to return a DataSet to the client then you will need to convert that dataset into string and then return it. Take a look at the GetCallbackResult below:

public string GetCallbackResult() {

string data = GetProductsByCategoryID(Int32.Parse(returnValue));

return data;

}

The GetCallbackResult calls GetProductsByCategoryID which takes in the categoryID and returns the Products as a string. Let's take a look at the GetProductsByCategoryID method.

private string GetProductsByCategoryID(int categoryID)

{

string connectionString = @"Server=localhost;Database=Northwind;Trusted_Connection=true";

SqlConnection myConnection = new SqlConnection(connectionString);

string query = "SELECT ProductName,QuantityPerUnit FROM Products WHERE CategoryID = @CategoryID";

SqlCommand myCommand = new SqlCommand(query, myConnection);

myCommand.Parameters.AddWithValue("@CategoryID", categoryID);

SqlDataAdapter ad = new SqlDataAdapter(myCommand);

DataSet ds = new DataSet();

ad.Fill(ds);

GridView gv = new GridView();

gv.ID = "gvProducts";

// You can also assign the CSS class here.

gv.DataSource = ds;

gv.DataBind();

// Create Html Text Writer

StringWriter sw = new StringWriter();

HtmlTextWriter htw = new HtmlTextWriter(sw);

gv.RenderControl(htw);

return sw.ToString();

}

Most of the code in the GetProductsByCategoryID method is standard code to access the database and retrieve and bind the data to the GridView control. The use of the StringWriter and HtmlTextWriter provides the ability to generate the HTML code for the GridView control. Once, the HTML is generated you can return it to the calling method.

Using HtmlTextWriter and StringWriter to Generate the HTML for the Controls

Since, you need to return the result as type string you can use several different methods of returning it. You can use the StringBuilder class to generate the HTML TABLE and then return the generated table as string. You can also make use of the HtmlTableCell class which creates a table dynamically. I find using the HtmlTextWriter and StringWriter very useful since they don't require much code and there is no hassle of appending the HTML like in the StringBuilder approach.

Even though the GridView's HTML is easily generated for some reason the assigned SkinID does not take effect. You can however use the CSS class to customize the look of your GridView.

 

Attaching the Event to the Button Click:

The next thing you need to do is to attach the JavaScript function to the button click. Take a look at the code below which performs this task.

<div>

Enter Category ID: <input type="text" id="txtCategoryID" name="txtCategoryID" />

<input type="button" value="Submit" onclick="GetProductsByCategoryID()" /><br />

<br />

<br />

<div id="MyDiv" runat="server">

</div>

The function GetProductsByCategory is fired whenever the button is clicked. Now, let's take a look at the GetProductsByCategoryID method implementation.

function GetProductsByCategoryID()

{

// txtCategoryID is the textbox

categoryID = document.getElementById("txtCategoryID").value;

CallServer(categoryID,'');

}

And finally the ReceiveServerData function which is used to receive the data from the server.

function ReceiveServerData(rValue)

{

document.getElementById("myDiv").innerHTML = rValue;

}

Take a look at the screen shot below.

Conclusion:

ASP.NET 2.0 Client Callbacks allows you to make server side calls without the postback. This results in increase performance and smoother user experience.

I hope you liked the article, happy coding!