Article Author: Pieter Siegers
Introduction
This is the follow-up article to http://www.asptoday.com/content.aspx, and aims to compare three popular Ajax .NET frameworks, Atlas, Anthem.NET and Ajax.NET professional. In the previous article, I introduced a couple of parallel simple samples that work with each of those frameworks, and I’m going to continue developing those here, (so if you haven’t read the previous article, you might want to do so now).
After having discussed some more examples that build around a real-time progressbar, I’ll discuss shortly a few key points with respect of the capabilities of each framework to ease Ajax development.
Then I’ll show you a simple feature-comparing table where you can determine which framework would suit you best with respect to your current development.
System Requirements
To run the sample code provided by the frameworks as well as included in the download material you will need to have the following:
- A web server running on Windows XP or Windows Server 2003 or later
- The .NET Framework version 1.x / 2.0
- VS.NET2003 / 2005 (see note) or Visual Web Developer
- A web browser – it can be IE6, IE7, FF 1.5 for Windows but also Safari 1.2+ on Mac OSX – all samples should work
Installing and Compiling the Sample Code
All the samples are written using C# with VS 2005 and were generated from a Web Site project. There are implementation specific samples you can obtain by downloading them from their respective websites. For more information, check the Related Links section.
For each of the frameworks discussed in this article and where possible there are specific samples available in the download material. Each sample has an install.txt file which describes what you should do in order to get the sample up and running quickly.
The directory structure of the download for this article is as follows: it contains three directories named AtlasSample, AnthemNETSample, and AjaxNETSample. Each one contains project files that you can open in VS.NET 2005 using Open | Web Site. But before doing so, you’ll need to add the corresponding libraries first.
The Sample Applications
In this section I will finish up the discussion around the sample applications.
Example 3: ProgressBar Waiting for the Web Server
This example first shows a simple version of a progressbar (see Figure 1) that notifies the user of work being done on the web server.
Atlas

Figure 1. Example 3 : Progressbar waiting for the web server in Atlas
Here, the callback is initiated by clicking the server button control:
<asp:Button ID=“btnFillTable1” OnClientClick=“preCBF_btnFillTable1()”…
This has a property OnClientClick to indicate it will run a client-side function called preCBF_btnFillTable1():
var cnt1 = 4000;
function preCBF_btnFillTable1() { document.getElementById(“divProgressBar1”).style.background = “white”; document.getElementById(‘txtPerc1’).value = “0%”; document.getElementById(‘btnFillTable1’).value = “Working…”; document.getElementById(‘btnFillTable1’).disabled = true; window.status = “Getting data from web server… “; AtlasSample.GetDoSomeWorkService.DoSomeWork(_ cnt1,postCBF_btnFillTable1);
}
As you can see from the code, the progressbar is simply a <div> control that changes its background color property. For the bordercolor having its width fixed and color visible at all times, the progressbar <div> is wrapped inside another <div>.
The function preCBF_btnFillTable1() calls the server method DoSomeWork() and simulates some work that takes 4 seconds (cnt1) to complete on the server:
[WebMethod]
public void DoSomeWork(int Cnt)
{ System.Threading.Thread.Sleep(Cnt);
{
In this case the server method only ticks away the amount of milliseconds passed on, and then returns to the JavaScript function postCBF_btnFillTable1():
function postCBF_btnFillTable1() {
document.getElementById(“divProgressBar1”).style.background = “yellow”;
document.getElementById(‘txtPerc1’).value = “100%”;
document.getElementById(‘btnFillTable1’).value = “Get data…”;
document.getElementById(‘btnFillTable1’).disabled = false;
window.status = “Getting data from web server… done.”;
}
This actually does a rather silly thing – it fills the progressbar’s <div> with the color yellow, but only after the web server has completed. While it works, you need a way to provide a more visible indication to show the web server is really doing its job.
During the callback, the control looks like Figure 2 (nothing seems to be happening):

Figure 2. Example 3:Progressbar while server method is running
After the work on the server is complete, the client notifies the user as shown in Figure 3:

Figure 3. Example 3:Progrssbar showing the work is completed
Anthem.NET
In Anthem.NET, things are a bit different since you can now use one of the special controls from the collection that comes with the library – here you use the <anthem:Button>:
<anthem:Button ID=“btnFillTable1” runat=“server”
OnClick=“btnFillTable1_Click1” Style=“z-index: 100; left: 20px;
position: absolute; top: 93px” Text=“Get data…” Width=“126px”
TextDuringCallBack=“Working…”
AutoUpdateAfterCallBack=“false” EnabledDuringCallBack=“False”
PreCallBackFunction=“preCBF_btnFillTable1”
PostCallBackFunction=“postCBF_btnFillTable1”
EnableViewState=“False” />
This is a completely new way of using a control and very well integrated into the way controls are programmed in ASP.NET. First note that some new unique properties have been added that make the use of the Anthem controls (here anthem:Button) much richer and ease web development.
For example, the properties PreCallBackFunction and PostCallBackFunction let you execute JavaScript functions before and after the callback process. TextDuringCallback is also a useful property which lets you set a text string, which is displayed during a callback. And AutoUpdateAfterCallBack lets you define if the control should auto update itself after a callback. Finally, EnabledDuringCallBack permits you to disable the control during the callback, which is very useful in applications where a button should be clicked only once per transaction.
Next, the function preCBF_btnFillTable1() is executed:
function preCBF_btnFillTable1() {
document.getElementById(“divProgressBar1”).style.background = “white”;
document.getElementById(‘txtPerc1’).value = “0%”;
window.status = “Getting data from web server… “;
}
Since the call into the method is absent here, how is it declared then? Well, the anthem:Button (and as a matter of fact, the other anthem-ized controls also) have a redefined the OnClick() event handler: it doesn’t do a postback but a callback. It is a bit of a trick, because in this framework, when the callback starts, the page with its viewstate and control collection that is to be updated is returned to the web server. There it is processed as usual, but when the result is returned, Anthem.NET intercepts it and passes only the necessary data returned to the JavaScript function that is needed to update the page controls.
The web server page method (as defined in the button control declaration) here is named btnFillTable1_Click1() and does the following:
protected void btnFillTable1_Click1(object sender, EventArgs e) {
this.blnWorking = true;
while (this.blnWorking)
{
System.Threading.Thread.Sleep(100);
iCounter++;
if (this.iCounter 50)
this.blnWorking = false;
}
}
What the server is doing here is just simulating work by counting slowly to 50 and then returning. In reality this is where you would do your own processing.
When the callback returns, the anthem:Button property PostCallBackFunction defines the function to execute:
function postCBF_btnFillTable1() {
document.getElementById("divProgressBar1").style.background = "yellow";
document.getElementById('txtPerc1').value = "100%";
window.status = "Getting data from web server... done.";
}
This simply colors the <div> yellow among a couple of other things. Although it is showing how Ajax-like web applications behave, it is not very useful yet, so I decided to add real-time web server progress to it. The result is the next and last to be covered
Ajax.NET Professional
Here, the button is of type HTML:
<input id="btnFillTable1" onclick="preCBF_btnFillTable1()"
The JavaScript function this time has a call into the page method:
var cnt1 = 4000;
function preCBF_btnFillTable1() {
document.getElementById("divProgressBar1").style.background = "white";
document.getElementById('txtPerc1').value = "0%";
document.getElementById("btnFillTable1").value = "Working...";
document.getElementById("btnFillTable1").disabled = true;
window.status = "Getting data from web server... ";
AjaxNETSample._Default.DoSomeWork(cnt1, postCBF_btnFillTable1);
}
The method DoSomeWork() is the same as was used previously and waits 4000 (cnt1) milliseconds. The callback returns and executes the function postCBF_btnFillTable1():
function postCBF_btnFillTable1() {
document.getElementById("divProgressBar1").style.background = "yellow";
document.getElementById('txtPerc1').value = "100%";
document.getElementById("btnFillTable1").value = "Get data...";
document.getElementById("btnFillTable1").disabled = false;
window.status = "Getting data from web server... done.";
}
As you can see, this is the same as with the other implementations.
Example 4: Progressbar Interactively Communicates with the Web Server
This last example will show a more advanced progressbar that will show your users real-time progress on the web server as shown in Figure 4.
Atlas

Figure 4. Example 4: The progressbar before starting the updates
To initiate the callback, click the Get data... button.
<asp:Button ID="btnFillTable3" OnClientClick="populateTable();
return false;"...
As expected, the JavaScript function populateTable() is executed:
var countStatus3 = 0;
var countRepeat3 = 0;
var ft;
var iMaxNum = 49;
function populateTable() {
window.status = "Getting data from web server... ";
document.getElementById('btnFillTable3').value = "Working...";
document.getElementById('btnFillTable3').disabled = true;
// clear div if already run once
if (countStatus3 -1) {
ClearProgressBar();
}
AtlasSample.GetUpdateCounterService.UpdateCounter(countStatus3,
postPopulateTable);
// continiously execute method….
ft = window.setTimeout(“populateTable()”, 250);
if (countStatus3 iMaxNum )
{
window.clearTimeout(ft);
countStatus3 = -1; // for next click
document.getElementById('btnFillTable3').value = "Get
data...";
document.getElementById('btnFillTable3').disabled = false;
window.status = "Getting data from web server... done.";
}
document.getElementById('txtcountStatus3').value = countStatus3;
}
The key is in the line:
ft = window.setTimeout("populateTable()", 250);
All this does is repeatedly execute the callback with an interval of 250 msec and returns the web server progress status. It does so until all the work is completed on the server.
The server method that gets called each time is UpdateCounter():
[WebMethod]
public int UpdateCounter(int iCounter)
{
System.Threading.Thread.Sleep(100);
iCounter++;
return iCounter;
}
Here the code simulates work by doing nothing, but of course in practice this would be some serious data processing that would return a real-time percentage, which is then returned to the client browser for processing.
The JavaScript function postPopulateTable() that is run each time the callback returns with data from the server is as follows:
function postPopulateTable(result) {
document.getElementById("divProgressBar2").style.backgroundColor =
"red";
document.getElementById("divProgressBar2").style.width = result*5 +
"px";
countStatus3 = result;
document.getElementById('txtPerc3').value = countStatus3*2 + "%";
if (countStatus3 50) {
countStatus3 = -1;
countRepeat3++;
}
}
Filling the <div> works as follows, the <div> that wraps divProgressBar2 has a fixed width of 250 px which means that the inner <div> can have a variable width of 0-250 px. The web server method works with a counter that counts from 0-50 which corresponds to 0-100% shown in the progressbar. This means that the progressbar should be filled 50 times with 5 px to completely fill the progressbar when 100% processing is reached.
Returning 50 from the server is actually a value computed on the server and not on the client. It is therefore an indication of real work done at the server which is reflected by the client progressbar.
When the progressbar needs refreshing the function ClearProgressBar() is executed:
function ClearProgressBar() {
if (countRepeat3 1) {
alert("Hey, you've already run this once! :-)");
}
else {
alert("Hey, you've already run this " + countRepeat3 +
" times! :-)");
}
document.getElementById("divProgressBar2").style.background = "white";
document.getElementById('txtPerc3').value = "0%";
countStatus3 = 0;
}
The function determines if the process has been run previously and then initializes the controls and a variable before repeating the process.
During the callback the example looks like Figure 5

Figure 5. Example 4: The progressbar being updated in real time
After the process on the web server has completed, the JavaScript execution is halted and the final result looks like Figure 6

Figure 6. Example 4 The progressbar upon completion
Anthem.NET
In Anthem.NET, the callback is started with a normal server button (you could of course use an anthem:Button also):
<asp:Button ID="btnFillTable3" OnClientClick="populateTable();
return false;"...
The function populateTable() is called:
var countStatus3 = 0;
var countRepeat3 = 0;
var ft;
var iMaxNum = 49;
function populateTable()
{
window.status = "Getting data from web server... ";
document.getElementById('btnFillTable3').value = "Working...";
document.getElementById('btnFillTable3').disabled = true;
// clear div if already run once
if (countStatus3 -1) {
ClearProgressBar();
}
// callback into server method using Anthem.NET and anonymous function
Anthem_InvokePageMethod(‘UpdateCounter’,[countStatus3],
function(result)
{
document.getElementById(“divProgressBar2”).style.backgroundColor =
“red”;
document.getElementById(“divProgressBar2”).style.width =
result.value*5 + “px”;
countStatus3 = result.value;
document.getElementById(‘txtPerc3’).value = countStatus3*2 + “%”;
if (countStatus3 50) {
countStatus3 = -1;
countRepeat3++;
}
}
// continiously execute method....
ft = window.setTimeout("populateTable()", 250);
if (countStatus3 iMaxNum) {
window.clearTimeout(ft);
countStatus3 = -1;
document.getElementById(‘btnFillTable3’).value = “Get data…”;
document.getElementById(‘btnFillTable3’).disabled = false;
window.status = “Getting data from web server… done.”;
}
document.getElementById(‘txtcountStatus3’).value = countStatus3;
}
The code above calls into the page method shows an alternative way, it uses an anonymous JavaScript function definition. The function populateTable() is executed continuously with the following code:
ft = window.setTimeout(“populateTable()”, 250);
This means that the function is repeatedly executed every 250 msec. When the web server returns a counter value of 50 (which resembles 100%) the callback stops:
window.clearTimeout(ft);
The next time the button is clicked, the progressbar is cleared and a message is displayed:
function ClearProgressBar() {
if (countRepeat3 1) {
alert("Hey, you've already run this once! :-)");
}
else {
alert("Hey, you've already run this " + countRepeat3 +
" times! :-)");
}
document.getElementById("divProgressBar2").style.background = "white";
document.getElementById('txtPerc3').value = "";
countStatus3 = 0;
}
Ajax.NET Professional
Here, the callback is initiated using a server-side button:
<asp:Button ID="btnFillTable3" OnClientClick="populateTable();
return false;"...
The function populateTable() is executed:
var countStatus3 = 0;
var countRepeat3 = 0;
var ft;
var iMaxNum = 49;
function populateTable() {
window.status = "Getting data from web server... ";
document.getElementById('btnFillTable3').value = "Working...";
document.getElementById('btnFillTable3').disabled = true;
// clear div if already run once
if (countStatus3 -1) {
ClearProgressBar();
}
AjaxNETSample._Default.UpdateCounter(countStatus3,
postPopulateTable);
// continiously execute method….
ft = window.setTimeout(“populateTable()”, 250);
if (countStatus3 iMaxNum) {
window.clearTimeout(ft);
countStatus3 = -1; // for next click
document.getElementById('btnFillTable3').value =
"Get data...";
document.getElementById('btnFillTable3').disabled = false;
window.status = "Getting data from web server... done.";
}
document.getElementById('txtcountStatus3').value = countStatus3;
}
This calls the web page method UpdateCounter():
[AjaxPro.AjaxMethod]
public int UpdateCounter(int iCounter)
{
System.Threading.Thread.Sleep(100);
iCounter++;
return iCounter;
}
Each time the callback returns, it updates the progressbar and the percentage textbox:
function postPopulateTable(result) {
document.getElementById("divProgressBar2").style.backgroundColor =
"red";
document.getElementById("divProgressBar2").style.width = result.value*5
+ "px";
countStatus3 = result.value;
document.getElementById('txtPerc3').value = countStatus3*2 + "%";
if (countStatus3 (iMaxNum + 1)) {
countStatus3 = -1;
countRepeat3++;
}
}
The function populateTable() is executed continuously until the web server returns it’s ready with its job and clearTimeout() stops the callbacks. Like the other examples, when clicking the button again, the progressbar and percentage textbox are initiated to their initial values.
That was it regarding the code details; now let’s compare these three frameworks and then finally look at the feature-comparing table.
Framework Comparison
I’d like to discuss a few observations now in comparing the three frameworks we’ve been looking at in detail.
Multiple Callbacks on a Page
The samples I’ve included use for each example a button, be it of type HTML, asp:Button, or anthem:Button. If you click on every button within short intervals, multiple callbacks are executed which could influence each other. And yes, they do, unfortunately. The effect varies with each framework though.
The first rule to consider is when using multiple callbacks that fire simultaneously, don’t use alerts. They will kill your Ajax functionality that is running at that moment in the background. In most of the frameworks and browsers, using alerts stops the JavaScript engine from continuing. I haven’t done detailed tests yet, but from what I’ve seen I’d say it’s simply better to avoid using alerts and use a <div> or label controls to indicate messages, warnings, and errors.
The second thing to consider is to not using framework specific controls if you don’t need to, they could well be influenced by a callback that wasn’t meant to update other controls on the page. For example, Anthem.NET includes for every callback the complete collection of anthem:xxx controls, and if you have them set to automatic update after a callback they will be reset to their initial viewstate value.
Capability to Reduce Development Time?
For all three frameworks, it is fairly easy to integrate them into web pages, whether they already exist or are being created from scratch.
For Atlas, adding Ajax functionality the way I showed is fairly simple, but it doesn’t reduce development time. It is however worth the price as the results in terms of application performance improvements and user-friendliness are in most cases surprising. But there’s more, Atlas has the capability to Ajax-ify any area by using the UpdatePanel. A web page that contains a GridView is wrapped into the UpdatePanel control and that’s about it. The use of web services makes it easy to add Ajax functionality to an existing page.
With Anthem.NET you have the ability to utilize a special control collection that is derived from the normal asp:xxx controls but adds additional useful functionality. This doesn’t really reduce development time however, but it feels exactly like normal ASP.NET-like web application development and that means it’s easy to integrate. Anthem.NET provides complete source control, which can be an advantage in those cases where the framework needs to be extended with extra functionality.
Finally, Ajax.NET Professional doesn’t provide a way to use web services nor does it provide a special control collection. It does however impose less load on the web server, which can have its benefits in some web scenarios.
web.config Changes and their Implications
Each framework requires some special settings in the web.config file. Both Anthem.NET and Ajax.NET Pro need simple settings while Atlas requires additional sections. It is important to follow the instructions that are provided by each framework, and in the case of Atlas you should copy the relevant sections to your web.config cautiously.
Ajax Framework Comparison Table
The following table provides a summary of support is provided by the various frameworks I’ve been using in these articles.
| Feature | MS Atlas | Anthem.NET | Ajax.NET |
|---|---|---|---|
| IDE support: | |||
| VS.NET 2003 | - | ![]() |
![]() |
| VS.NET 2005 | ![]() |
![]() |
![]() |
| ASP.NET v1.1 | - | ![]() |
![]() |
| ASP.NET v2.0 | ![]() |
![]() |
![]() |
| Pre callback JavaScript | ![]() |
![]() |
![]() |
| Post callback JavaScript | ![]() |
![]() |
![]() |
| Tight integration in the page lifecycle | ![]() |
![]() |
- |
| Release Name | March Release | Anthem-1.0.0 | Ajax.NET Pro for .NET v2.0 |
| More Information | http://atlas.asp.net | http://sourceforge.net/projects/anthem-dot-net | http://dotnet2.schwarz-interactive.de/ |
There is considerable cross-browser support. When I first started this article, I prepared an extended version of this table which indicated which of the samples I’ve presented work on each browser, but over the last couple of months support has improved, which means all of the samples work with all three frameworks on all of the following browsers:
- IE6+ (PC)
- IE7 Beta2 Preview
- Mozilla FireFox 1.5+ (PC)
- Safari 1.3 and 2.0+ (Mac OS X)
Note: For the examples to work well, FireFox and Safari need anonymous access in IIS 6, which can complicate things in the case of intranet development.
Note 2: The example worked in FF after I changed the following JavaScript function call definition:
..OnClientClick=“preCBF_btnFillTable1();”
into
..OnClientClick=“preCBF_btnFillTable1(); return false”.
Conclusion
In this two part article I have discussed Ajax with respect to ASP.NET development. I’ve shown you three of the popular Ajax frameworks that support ASP.NET web application development. I’ve discussed where each framework differs from the others and what their strong and weak points are. Several examples were used to show how to integrate the various frameworks into the .your code base using each of the frameworks.
This set of articles has provided a good idea of what it means to have Ajax support in your development, and also where you can apply this exciting new way of updating specific controls or areas in your web pages. Lastly, I presented a table that provides a summary of what has been discussed in the articles so that you can easily determine which framework will work best for you.


