5,693,936 members and growing! (16,924 online)
Email Password   helpLost your password?
Web Development » Ajax and Atlas » Atlas     Beginner License: The GNU General Public License (GPL)

Using Ajax to display the progress of an ASP.NET server task

By jlchereau

A progress bar implementing ASP.NET Ajax Extensions 1.0
C# (C# 2.0, C# 3.0, C#), Javascript, HTML (HTML), Windows (Windows, WinXP, Win2003, Vista), .NET (.NET, .NET 3.5, .NET 3.0, .NET 2.0), ASP.NET, IIS (IIS 5.1, IIS 6, IIS 7, IIS), Visual Studio (VS2005, VS2008, Visual Studio), Ajax, Design, Architect, Dev

Posted: 18 Dec 2007
Updated: 3 Jan 2008
Views: 2,147
Bookmarked: 6 times
Announcements
Loading...



Search    
Advanced Search
Sitemap
1 vote for this Article.
Popularity: 0.00 Rating: 5.00 out of 5
0 votes, 0.0%
1
0 votes, 0.0%
2
0 votes, 0.0%
3
0 votes, 0.0%
4
1 vote, 100.0%
5
Note: This is an unedited contribution. If this article is inappropriate, needs attention or copies someone else's work without reference then please Report This Article

Progress report in run mode

Introduction

Our objective is to display an Ajax progress bar which indicates the progress of a server task. Our environment is ASP.NET 2.0 on Windows and IIS and our progress bar uses ASP.NET Ajax Extensions 1.0 which you can download and install from http://www.asp.net/ajax/.

Background

This article refers to the open-source controls of “Memba Velodoc XP Edition” which you can download from http://www.velodoc.com/en/download.htm (this page links to Codeplex, Google code and Sourceforge.NET) and which are distributed under the GPL license. These controls include a progress bar which we demonstrate in this article. You can experiment these controls live at http://www.velodoc.net/.

Using the code

In Visual Studio 2005, create a new ASP.NET Ajax-Enabled Web Site and add a reference to Memba.WebControls.XP.dll which contains the progress report server control. Memba.WebControls.XP.dll is part of Memba Velodoc XP Edition. Source code is available at the download location cited above.

Open the Default.aspx page and add the ProgressReport server control, either by dragging and dropping the control after adding it to the toolbox or simply by adding the following code between the existing <form> tags:

<form id="form1" runat="server">
<asp:ScriptManager ID="ScriptManager" runat="server" ></asp:ScriptManager>
<mbui:ProgressReport ID="ProgressReport" runat="server"  
    DefaultText="Waiting..."
    Width="400px"
    Interval="1000"
    BarCssClass="cssProgressBar"
    FillerCssClass="cssProgressFiller" 
    HandlerUrl="~/progressHandler.ashx"
    TextFormat="Value 1: {0}<br/>Value 2: {1}" ></mbui:ProgressReport>
<input type="button" onclick="go();" value="Go" />
</form> 

Also add an html button to start the progress bar using the onlick event.

You may have to register the control at the top of the page, using the following statement:

<%@ Register Assembly="Memba.WebControls.XP" Namespace="Memba.WebControls" TagPrefix="mbui" %> 

The progress bar consists of two nested DIV’s. The outer DIV constitutes the frame of the progress bar and the inner DIV constitutes the filled section which represents the progress. Add the following styles just above the </head> closing tag of your page:

<style  type="text/css">
<!--
div.cssProgressBar
{
 border:solid 1px DarkGreen !important;
 padding:1px;
 background-color:White;
}
div.cssProgressFiller
{
 background-color:DarkGreen !important;
 height:10px;
}
//-->
</style>

Your ProgressReport control should now look like follows:

Progress report in design mode

ProgressReport has two properties which work in conjunction:

  1. HandlerUrl points to an http handler which should return a JSON string in a specific format; you could use an ASP.NET page to return this formatted string, but a handler is leaner in this case because ASP.NET pages have a complex lifecycle.
  2. TextFormat is the formatting string used to display a textual description of the progress using the data returned by the http handler.

Now create a new generic handler called progressHandler.ashx:

Adding a new generic handler in Visual Studio 2005

This handler would generally query the progress of a task executing on the server. One could imagine a loop which would iterate through the pages of a multipage report and regularly update the current page number in memory (application state, session state or context cache). The handler would query the memory and return the progress in percentage of the total number of pages. The progress bar defines the interval at which the handler is called. We have made our example simpler as we simply increment a static counter.

Add the following two statements at the top of your handler:

using Memba.WebControls; //ProgressData4JS
using System.Web.Script.Serialization; //JavaScriptSerializer

Implement your handler as follows:

public class progressHandler : IHttpHandler
{
    private static int _Counter;
    
    public void ProcessRequest (HttpContext context)
    {
        //First, make sure the content is not cached because we need
        //"real-time" progress report
        
        //Using headers or cache attributes to set the cache policy
        //should be equivalent
        context.Response.AppendHeader("Cache-Control",
            "no-cache, no-store, must-revalidate");
        context.Response.AppendHeader("Expires", "-1");
        context.Response.AppendHeader("Pragma", "no-cache");

        //but the following does not work in IIS 7 (Vista 64-bit OS),
        //which requires the code above
        context.Response.Cache.SetCacheability(HttpCacheability.NoCache);
        context.Response.Cache.SetRevalidation(
            HttpCacheRevalidation.AllCaches);
        context.Response.Cache.SetNoStore();
        context.Response.Cache.SetNoServerCaching();
        context.Response.Cache.SetExpires(DateTime.Now);
        
        //Create a progress data object which will be used for JSON 
        //serialization
        ProgressData4JS objProgressData4JS = new ProgressData4JS();
        
        //Fill the progress data until progress reaches 100%
        if (_Counter < 100)
        {
            objProgressData4JS.IsComplete = false;
            objProgressData4JS.FillRatio = String.Format("{0}%", _Counter);
            objProgressData4JS.TextValues = new object[] {
                "PENDING",
                _Counter };
            objProgressData4JS.ErrorMessage = null;
            _Counter+=10;
        }
        else //Once progress reaches 100% we are done
        {
            objProgressData4JS.IsComplete = true;
            objProgressData4JS.FillRatio = "100%";
            objProgressData4JS.TextValues = new object[] {
                "COMPLETE",
                _Counter };
            objProgressData4JS.ErrorMessage = null;
            _Counter = 0;
        }
        
        //Serialize progress data
        JavaScriptSerializer objJavaScriptSerializer =
            new JavaScriptSerializer();
        string sResponse =
            objJavaScriptSerializer.Serialize(objProgressData4JS);
        context.Response.ContentType = "text/json";
        //Some use "application/json"
        
        //Write the response
        context.Response.Write(sResponse);
        context.ApplicationInstance.CompleteRequest();
        //See: http://support.microsoft.com/kb/312629
        //context.Response.End();
    }
 
    public bool IsReusable {
        get
        {
            return true;
        }
    }
}

Whatever the task you execute on your server and you want to report progress on, always use a ProgressData4JS object which you write to the response stream using JSON serialization. The progress bar of the ProgressReport control uses the FillRatio property of the PorgressData4JS object to display the status of the progression. ProgressData4JS also has a property called TextValues which is an array of objects used to display the text under the progress bar in conjunction with the TextFormat property of the ProgressReport control. In our example, when the progress has reached 100%, TextValues contains “COMPLETE” and “100”. The TextFormat property of our ProgressReport is “Value 1: {0}<br />Value2: {1}”. The result displayed will be:

Value 1: COMPLETE
Value 2: 100

Now, we need to write the Javascript code to start the progress report. Add the following script just before the </body> closing tag of your page.

<script type="text/javascript">
<!--
//Click event handler for the Go button
function go()
{
    //Get a reference to the progress control
    var _c = $find("<%= ProgressReport.ClientID %>");
    //Add an event handler for the complete event
    _c.add_complete(onComplete);
    //Start progress report
    _c.start();
}
//Complete event handler for the progress report
function onComplete(e)
{
    alert("complete");
}
//-->
</script>

The script implements two event handlers:

  • A click event handler for the go button, which starts the progress;
  • A complete event handler for the progress report control, which displays an alert when the server task is complete.

Press F5 to run the project and click the go button to see the progress bar progressing.

Points of Interest

This progress bar is an easy to use server control based on ASP.NET Ajax extensions. It not only displays a progress bar but also a highly flexible textual description. For more advanced developers, the source code of the progress bar is available at Codeplex, Google code and Sourceforge.NET and is commented in great details.

History

  • Version 1.0 dated 18 Dec 2007

License

This article, along with any associated source code and files, is licensed under The GNU General Public License (GPL)

About the Author

jlchereau


Other Articles:



My work at Memba


You can check what Memba does at our corporate web site.

I am currently working on two projects:
- VELODOC, a file transfer online service and software product which you can try at http://www.velodoc.net;
- CITADOC, a knowledge base/wiki online service and software product which can be managed and edited in Microsoft Office and which will be released in the second half of 2008.

The XP edition of these projects is the open source core released under the GPL license.


Occupation: Other
Company: Memba
Location: United Kingdom United Kingdom

Article Top
Sign Up to vote for this article
You must Sign In to use this message board.
FAQ FAQ Search Search Messages 
 Layout  Per page   
  (Refresh) 
-- There are no messages in this forum --

General General    News News    Question Question    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

PermaLink | Privacy | Terms of Use
Last Updated: 3 Jan 2008
Editor:
Copyright 2007 by jlchereau
Everything else Copyright © CodeProject, 1999-2008
Web08 | Advertise on the Code Project