Introduction
This article describes how to update the data in an ASP.NET 2.0 DataView
control through AJAX.
Problem description
Let's consider that there is an e-commerce application that allows customers to buy products on the internet. Each time a sale is done, the remaining products quantity is updated. Let's also consider that it is necessary to monitor those quantities in real time (this can be required in the case of high volume sales and the necessity to frequently order the required products). In such a case, it will be useful to have a web page with the required products and units in stock data that will be updated through asynchronous calls on a required time interval (let's say 5 sec). When I had a request to develop a similar page, I spent many hours on the internet trying to find any working sample that could give me an idea on how to do this, and I didn't succeed. Most of the articles had beautiful words, but didn't have any line of code; other articles had samples that didn't work. So, after some time, I came up with my own approach on how to make this work, and I hope this article will help other people who are trying to understand AJAX.
Background
The sample uses the data from the Products table in the Northwind database. The approach is based on using an XmlHttpRequest
object using which you can send/get any data from/to a server using JavaScript. To implement AJAX calls, you actually need to have two web pages: one that is visible to the end user, and another that actually generates the required content for the first web page. The first page calls the second one through an XmpHttpRequest
implemented in JavaScript.
Using the code
In the the sample below, we will have two web pages:
- Default.aspx - the page that will be shown to the end user
- DataGrid.aspx - will provide the content to the Default.aspx page that will be updated every 5 seconds.
As it was told, the sample uses the Northwind database, the connection string to which is provided in the web.config file:
<appSettings>
<add key="DSN"
value="server=localhost;Integrated Security=SSPI;database=Northwind" />
</appSettings>
The Business Logic Layer is located in the App_Code\BLL subfolder, and contains the ProductsBLL
class that has a method GetProducts()
that actually returns all the products for CategoryId
=1 from the Products table in the Northwind database.
{
public static void GetProducts(DataSet ds)
{
string sqlString = "SELECT ProductId, ProductName, " +
"QuantityPerUnit UnitPrice, UnitsInStock " +
"FROM Products WHERE CategoryId=1 " +
"order by ProductName";
SqlHelper.FillDataset(SqlHelper.connection(),
CommandType.Text, sqlString, ds,
new string[] { "Products" });
}
}
The above method uses the FillDataset
method from the Data Access Layer which is located in the App_Code\DAL subfolder and contains a class SqlHelper
that contains a collection of data access methods. The SqlHelper
class was created based on Open Source Application Blocks data access classes, and can be successfully used to access data from a SQL Server database.
Let's now consider the DataGrid.aspx web page. This page contains the Label1
control and the GridView
control gvGrid
that are both populated on the Page_Load
event. The DataView
control is populated with data from the products data set, and Label1.Text
is updated with the current date/time.
protected void Page_Load(object sender, EventArgs e)
{
DataSet ds = new DataSet();
ProductsBLL.GetProducts(ds);
gvGrid.DataSource = ds;
gvGrid.DataBind();
Label1.Text = "Units in Stock for: " + DateTime.Now.ToString();
}
The Default.aspx page contains a <div>
section with id="GridSection"
and an Input button btnGet
that calls the AJAX JavaScript function doCall()
on the Click event. The data that will be received through AJAX calls will be placed inside the <div>
element.
<input id="btnGet" type="button" value="Get Data" onclick="doCall()"/>
.
.
.
<div id= "GridSection">
</div>
Now, let's consider the Ajax.js JavaScript that actually does the whole job.
var client=null;
if (window.XMLHttpRequest)
{
client = new XMLHttpRequest();
}
else if (window.ActiveXObject)
{
client = new ActiveXObject("Microsoft.XMLHTTP");
}
function doCall()
{
try
{
var url="DataGrid.aspx"
url=url+'?d='+Date();
client.open("GET", url);
client.onreadystatechange = callBack;
client.send();
}
catch(ex)
{
alert(ex.message);
}
setTimeout('doCall()', 5000);
}
function callBack(response)
{
try
{
if(client.readyState == 4 && client.status == 200)
{
xmlDocument = new ActiveXObject('Microsoft.XMLDOM');
xmlDocument.async = false;
xmlDocument.loadXML(client.responseText);
vargridNode=xmlDocument.selectSingleNode(
'/html/body/form/div[@id="Grid"]');
document.getElementById("GridSection").innerHTML=gridNode.xml;
}
}
catch(ex)
{
alert(ex.message);
}
}
To test the sample, open the Default.aspx page and click the "Get Data" button. The page will be populated with the DataView
with products data from the Products table. The data in the DataView
is refreshed every 5 seconds. To test this functionality, open the Northwind database Products table and change the UnitsInStock
field's data for some product from CategoryId
=1. The data on the Default.aspx web page will be changed in 5 seconds without being posted back.
Points of interest
Using the above technique, it is possible to update various parts of a page with different data asynchronously, which can be useful when working with data that should be refreshed to the user not only when the user posts back a page but rather at certain time intervals.
History
N/A.