USING AJAX.NET Library by azamsharp

Abstract

AJAX (Asynchronous JavaScript and XML) allow you to make server side calls without a Postback.
This increases the performance since you do not have to wait for the whole page to refresh to view the changes. In this article I will explain how to make asynchronous calls using the AJAX.NET library. The article also briefly discusses the effect of ViewState on the performance of the application.

Introduction

The concept of remote scripting was introduced by Microsoft in the form of embedded Java applets in the page which communicated with the server. The problem with that approach was that you must have Java enabled on your browser for it to work. Later JavaScript Remote Scripting was introduced which enabled developers to make asynchronous calls using DHTML and JavaScript.

In this article I will show how you can take a step further and make asynchronous calls using the AJAX.NET library which easily merge with the .NET framework.

System Requirements

To run the code for this sample you should have

  • AJAX.NET Class Library
  • VS.NET
  • MSDE or SQL Server with the Northwind database installed.

Installing and Compiling the Sample Code

The sample code for this article consists of a VS.NET project. The project was originally created in Visual Studio.NET 2003. If you are using Visual Studio.NET 2005 BETA I or BETA II then you can easily upgrade it using a Visual Studio.NET 2005 BETA built in converter.

What is a Postback?

Postback is the communication between the client and the server. Consider a situation where you have a form populated with input controls. You fill the input controls and submit the form. Your request will be sent to the server for processing and then it will be returned to you with the result. This process is known as Postback.

Postback and ViewState

Whenever you send a request to the server through the server control the page keeps track of the state of the control. This is accomplished by storing the state of the control in the ViewState variable. If you have several controls on the form then the ViewState size will be very large.

In the example below I have used a single TextBox. I wrote some text in the TextBox and pressed the Postback button to send my request to the server.

The user interface is given below:

User Interface of Demo1 Page
The ViewState generated for this page is given in the screen shot below:

ViewState Generated by a TextBox Control
Most forms will only contain a single TextBox. To give this ViewState a reality test I included several controls on the form. In the example below, I have generated the user interface by dynamically creating the controls and adding them to the panel control.

The new user interface will look like the screen shot below:

Dynamically Created Server Controls
Now let’s observe the source code which enables the creation of the controls:

private void Page_Load(object sender, System.EventArgs e)
{
	BuildControls();
}
// This method will build the controls dynamically
private void BuildControls()
{
	// Create a datagrid control
	DataGrid myDataGrid = new DataGrid();
	myDataGrid.DataSource = GetCategories();
	// create 5 textboxes
	for(int i=1;i<=5;i++)
	{
	TextBox myTextBox = new TextBox();
	// add to the panel controls
	pnControls.Controls.Add(myTextBox);
	}
	// add datagrid to the panel control
	pnControls.Controls.Add(myDataGrid);
	pnControls.DataBind();
}

// This method returns the dataset filled with the Categories table
private DataSet GetCategories()
{
	string connectionString = (string) ConfigurationSettings.AppSettings["ConnectionString"];
	SqlConnection myConnection = new SqlConnection(connectionString);
	SqlDataAdapter ad = new SqlDataAdapter("SELECT * FROM Categories",myConnection);
	DataSet ds = new DataSet();
	ad.Fill(ds,"Categories");
	return ds;
}

The code did not demonstrate anything fancy. It simply created the controls dynamically and added it to the panel control. Here is the ViewState generated for the page:

View State Created by Dynamically Created Server Controls
Now the size of the asp .net file transferred between the IIS and the client is bigger. My whole idea in presenting the demo is to show that ViewState can be very costly when you have several controls on the page triggering the Postback event. When you do a Postback the ViewState is passed to the server and than back again to the client.

AJAX to the Rescue

As mentioned in the introduction, AJAX allows you to execute the server side methods without making a Postback. This means that you will not need to refresh the page to see the new results. There are several ways to make server side calls from the client, and these include Callbacks, Atlas etc. I will explain how you can make client calls using AJAX.NET library. There is one more article on DHTML tooltips using Ajax .Net that you may be interested in.

Downloading AJAX.NET Library

AJAX.NET library is created by Michael Schwarz and is available as a free download from his website (http://ajax.schwarz-interactive.de/csharpsample/default.aspx).

Getting Started With AJAX.NET Library

Once you have downloaded AJAX.NET Library from the link provided above you are ready to use AJAX. All you need to do now is to make a reference to the Ajax.dll in your project. After making reference you just need to add the following few lines to your web.config file.

<configuration>
<system.web>
<httpHandlers>
<add verb="POST,GET" path="ajax/*.ashx"
type="Ajax.PageHandlerFactory, Ajax" />
</httpHandlers>

...
<system.web>
</configuration>

Returning a Simple String from the Server Method

Let’s start with a very basic example.
In this example I will make a call from the client side onLoad event which will return a string from the server side method and display it on the screen in the form of an alert box.

I assume that you have already made a reference to the Ajax.dll in your project and made the required adjustments in the web.config file. Now you are ready to use the AJAX.NET library. First thing I will show you is how to initialize the AJAX.NET library, and this is demonstrated below:

public class Demo3 : System.Web.UI.Page
{
	private void Page_Load(object sender, System.EventArgs e)
	{
		// Initializing AJAX.NET Library
		Ajax.Utility.RegisterTypeForAjax(typeof(Demo3));
	}
}

As you can see we have registered our class name with the AJAX.NET library.

Now let’s create a small method that will be called from the client side. This method will simply return a string “Hello World” to the client.

public string PrintHelloWorld()
{
	return "Hello World";
}

The method which you are trying to call from the client side must be marked with the [Ajax.AjaxMethod] attribute. The code below shows how to call the method from the client on the onLoad event.

<body onload="CallHelloWorld()">
<form id="Form1" method="post" runat="server">
</form>
</body>
</HTML>
<script language =javascript>
function CallHelloWorld()
{
	AjaxDemoReturnString.PrintHelloWorld(CallHelloWorld_CallBack);
}

function CallHelloWorld_CallBack(response)
{
	// check that if any error has been returned
	if(respone.error == null)
	{
		// displays the message on the screen
		alert(response.value);
	}
}
</script>

This CallHelloWorld() method is called when the page is loaded and makes a call to the server side method AjaxDemoReturnString.PrintHelloWorld(). AjaxDemoReturnString is the name of the class and PrintHelloWorld is the name of the method which is marked with the [Ajax.AjaxMethod] attribute. When you run this demo a simple message “Hello World” will be displayed on the screen.

Sending Parameters to the Server Method

The example above demonstrates how to return a string from the method. In the example below, I will show you how to pass parameters to the server’s method. I am going to pass the username to the server method and display a greeting message. Let’s look at the simple server method below:

[Ajax.AjaxMethod]
public string GreetUser(string userName)
{
	return "Hello, " + userName;
}

As you can see all that the method does is concatenate “Hello” at the beginning of the string.

<input type="button" value="Greet me!" onclick="GreetUser()" />

Attach the button click event to call GreetUser() function.

<script language = "javascript">
function GreetUser()
{
	// get the username from the textbox
	var username = document.getElementById("txtUserName").value;
	Demo3.GreetUser(username,GreetUser_CallBack);
}

function GreetUser_CallBack(response)
{
	alert(response.value);
}
</script>

The screen shot of the result is given below:


Displaying Passed Parameters Using Alert Box

I am sure you have understood the fundamentals behind the AJAX.NET library. Now let’s see some advanced uses of AJAX.

Returning a Dataset

The Dataset is among the most commonly used data carrier object in the Microsoft.NET framework. I use it often to bind data to the Datagrid control. In this example I will demonstrate how one can bind the data from the Dataset to the table without using Postback.

Firstly a sever side method is required which will return a Dataset. In the example below I used the Northwind database which is shipped with SQL SERVER 7 and SQL SERVER 2000. If for some reason you do not have the database installed on your machine, then you can download it from the link below:

Download Northwind Database

The method GetDataSet() simply populates the Dataset with the data from the Categories table.

// This method returns the dataset to the client
[Ajax.AjaxMethod]
public DataSet GetDataSet()
{
string connectionString = (string) ConfigurationSettings.AppSettings["ConnectionString"];
SqlConnection myConnection = new SqlConnection(connectionString);
SqlDataAdapter ad = new SqlDataAdapter("SELECT * FROM Categories",myConnection);
DataSet ds = new DataSet();
ad.Fill(ds,"Categories");
return ds;
}

Now I will show how to call the GetDataSet() from the client side and populate the HTML table.

<script language="javascript">
function BindDataSetToTable()
{
AjaxDemoReturnDataSet.GetDataSet(BindDataSetToTable_CallBack);
}
function BindDataSetToTable_CallBack(response)
{
// Check that if any errors are returned
if(response.error == null)
{
// get the value from the response into the var object
var ds = response.value;
if(ds!=null && typeof(ds) == "object" && ds.Tables!=null)
{
var s = new Array();
s[s.length] = "<table border = 1>";
// loop through the dataset and create rows
for(var i=0;i<ds.Tables[0].Rows.length;i++)
{
s[s.length] = "<tr>";
s[s.length] = "<td>" + ds.Tables[0].Rows[i].CategoryID + "</td>";
s[s.length] = "<td>" + ds.Tables[0].Rows[i].CategoryName + "</td>";
s[s.length] = "<td>" + ds.Tables[0].Rows[i].Description + "</td>";
s[s.length] = "</tr>";
}
s[s.length] = "</table>";
// Display1 is the name of the span tag where the table is going to be displayed
document.getElementById("Display1").innerHTML = s.join("");
}
}
}
</script>

Let’s see what is going on in the BindDataSetToTable_CallBack() method. I got the response object which has the value property containing the Dataset. I copied the Dataset into a var type variable so I could perform iteration on it. I then created a new array object which acts as a StringBuilder object and contains the html code to generate the table. A for loop was used to iterate through the dataset and get the rows from the specified columns. Finally, I used the span tag of id Display1 to display the table on the screen.
Below is the screen shot of the table displayed on the screen:

Image5.JPG: HTML Table Populated Using Dataset
One of the interesting things to note is the ViewState generated for the page.

Image6.JPG: ViewState Generated When Using AJAX
As you can see, the ViewState generated is much less than it was when server controls were used to display the data.

Returning a Custom Object

Most Enterprise Applications work with Entity Classes instead of Dataset objects. I will show you that binding a custom object is as simple as binding a Dataset to the HTML Table.

Creating the Categories and CategoryDetails Classes

CategoryDetails class will map to the Categories table in the Northwind database.The code below shows the CategoryDetails class:

// This class defines the Categories
[Serializable]
public class CategoryDetails
{
	private int _categoryID = 0;
	private string _categoryName = null;
	private string _categoryDescription = null;
	public int CategoryID
	{
		get { return _categoryID; }
		set { _categoryID = value; }
	}
	public string CategoryName
	{
		get { return _categoryName; }
		set { _categoryName = value; }
	}
	public string CategoryDescription
	{
		get { return _categoryDescription; }
		set { _categoryDescription = value; }
	}
}

Notice the [Serializable] attribute on the class. The [Serializable] tag is compulsory since we are going to access the class properties on a different thread. Now let’s see the Categories class which contains the method GetCategories().

public class Categories
{
	// Declare an array list to hold the collection
	private ArrayList categoriesList = new ArrayList();
	public Categories()
	{
	}
	public ArrayList GetCategories()
	{
		string connectionString = (string) ConfigurationSettings.AppSettings["ConnectionString"];
		SqlConnection myConnection = new SqlConnection(connectionString);

		SqlCommand myCommand = new SqlCommand("SELECT * FROM Categories",myConnection);
		SqlDataReader reader = null;
		try
		{
			myConnection.Open();
			reader = myCommand.ExecuteReader();
			while(reader.Read())
			{
				CategoryDetails category = new CategoryDetails();
				category.CategoryID = (int) reader["CategoryID"];
				category.CategoryName = reader["CategoryName"] as String;
				category.CategoryDescription = reader["Description"] as String;
				// Add to the ArrayList
				categoriesList.Add(category);
			}
		}
		finally
		{
			myConnection.Close();
			myCommand.Dispose();
		}
		// return the collection object
		return categoriesList;
	}
}

The GetCategories() method simply fills the ArrayList categoriesList with the rows from the Categories table in the Northindwind database. You can call the GetCategories() method from the code behind contained in the ASP.NET Page.

[Ajax.AjaxMethod]
public ArrayList GetCategories()
{
Categories category = new Categories();
ArrayList catList = category.GetCategories();
return catList;
}

Remember to make the method with the [Ajax.AjaxMethod] attribute or else you would not be able to call the method from the client script. All that is left to do is to call the GetCatories() method from the JavaScript code.

<script language = "javascript">
function DisplayCategories()
{
AjaxDemoReturnCustomObject.GetCategories(DisplayCategories_CallBack);
}
function DisplayCategories_CallBack(response)
{
var list = response;
if(list!=null && typeof(list) == "object")
{
var s = new Array();
s[s.length] = "<table border = 1>";
// loop through the arraylist and create rows
for(var i=0;i<list.value.length;i++)
{
s[s.length] = "<tr>";
s[s.length] = "<td>" + list.value[i].CategoryID + "</td>";
s[s.length] = "<td>" + list.value[i].CategoryName + "</td>";
s[s.length] = "<td>" + list.value[i].CategoryDescription + "</td>";
s[s.length] = "</tr>";
}

s[s.length] = "</table>";

// Display1 is the name of the span tag where the table is going to be displayed
document.getElementById("Display1").innerHTML = s.join("");
}
}
</script>

The code above is quite similar to the one I demonstrated earlier in which I used a Dataset to populate the HTML Table. The function DisplayCategories_CallBack() receives the ArrayList object from the server side method GetCategories(). After receiving the ArrayList I simply iterated through the list and assigned the public properties defined in the CategoryDetails class to the table cell.

Conclusion

In this article you’ve seen how to avoid unnecessary Postbacks by making client side asynchronous calls using the AJAX.NET Library. You also learned that AJAX minimizes the ViewState of the page which leads to high performance applications.