Using HTTP Handlers to Create a Progress Bar Control

Using HTTP Handlers to Create a Progress Bar Control

by Matt Rutledge

The HTTP Pipeline

ASP.NET uses a pipeline model to process the requests to the scripting engine. Here is generally how the pipeline model works.

  1. An HTTP request is passed to an instance of the HttpRuntime() class.
  2. The HttpRuntime() object examines the request to find out which application to send the request to.
  3. Then .NET uses a HttpApplicationFactory to either create or find an application.
  4. Once the proper application is found the request is sent to through any HttpModules that are running on that application.
  5. After the modules have operated on the application the application uses a HttpHandlerFactory to either find or create any handler objects.
  6. The final step is to deliver the application.

Take a look at the following figure for a visual representation of the HTTP Processing Pipeline.

HTTP Processing Pipeline

What is a HTTP Handler?

So What exactly is a Http Handler? Well, HTTP handlers are the .NET components that implement the System.Web.IHttpHandler interface. Any class that implements the IHttpHandler interface can handle incoming HTTP requests.

With Http Handlers you can create your own file extensions, do certain tasks every time a page with a specific extension is loaded, create progress bars to show status, etc., the list goes on and on.

When you implement any interface you have a certain number of functions that you will need to implement. The IHttpHandler interface has two functions that you will need to write. They are the ProcessRequest() function and the IsReuseable() function. The former is the heart of the Http Handler. The latter strictly tells the ASP.NET worker process whether it can reuse this Http Handler or not.

How do you create a HTTP Handler?

As I mentioned above you need to implement the ProcessRequest() and IsReuseable() functions in your own class. So let's create our own class. If you use Visual Studio .NET you can create a new Web solution by doing the following:

  1. Go to File->New->Project
  2. Go to the Visual C# Projects Folder and choose a ASP.NET Web Application
  3. Give the project a name and click "OK"

Now that you have a new C# Web project created you need to add a class to your project. I called mine CHttpProgressHandler. Once you have the class up you will need to inherit from the IHttpHandler interface. Then create a public function called ProcessRequest() that takes the HttpContext as a parameter and then create a public property called IsReusable that implements the get property. The code should look something like the following:




using System;

using System.IO;

using System.Web;

using System.Web.UI;

using System.Web.UI.WebControls;



namespace MyProgressBar

{

  /// <summary>

  /// Summary description for CHttpUploadHandler.

  /// </summary>

  public class CHttpProgressHandler : IHttpHandler

  {

    public CHttpProgressHandler()

    {

      //

      // TODO: Add constructor logic here

      //

    }



    #region IHttpHandler Members

    public void ProcessRequest(HttpContext context)

    {

    // TODO:  Add CHttpProgressHandler.ProcessRequest implementation

    }



    public bool IsReusable

    {

      get

      {

        return true;

      }

    }

    #endregion

  }

}

This is the base of all HttpHandlers. Any time that you start creating an Http Handler the class should look like the above code. Right now this Handler does absolutely nothing. So let's make it do something. One request that is seen a lot is creating a progress bar to show the user how long a particular process is going to take. Let's implement our Handler to do exactly that; to show the user how long a certain process will take.

Before you get to caught up in what the logic of the Handler is let's think about all the elements you will need to implement this progress indicator. First you will need a way to display a progress bar on a page. There are a lot of controls out there that you can download if you would like; we are going to create our own. Then you need a process that takes a certain amount of time to complete; for this you can implement a loop on a separate page that is triggered by an event. When that event is triggered you need to pop-up the progress bar. So you will need two pages, one for to implement a long process, and one to show the progress.

Let's implement our very own Progress Bar Control. To do this you will need to add another class to your project and inherit from the WebControl class and the INamingContainer interface. You will have two properties to set, the foreground color and the background color. Then you need to implement the render function to draw the progress bar. Here is the code for the Progress Bar Control:

Note: This is not a tutorial on how to create controls.



using System;

using System.Web.UI;

using System.Web.UI.WebControls;

using System.ComponentModel;



namespace Progress

{

  /// <summary>

  /// Progress bar control is used to display the progress or 

  /// status of a particular process.

  /// </summary>

  [DefaultProperty("Text"), ToolboxData("<{0}:ProgressBar runat=server>

    </{0}:ProgressBar>")]

  public class ProgressBar : WebControl, INamingContainer 

  {



    // Member variables

    private int nProgress      = 0;    // Percentage out of 100

    private int nPercentOfProgress  = 0;    // Percentage in 20ths



    /// <summary>

    /// Default Constructor

    /// </summary>

    public ProgressBar() 

    {

      // Set the default colors of the control

      this.BackColor = System.Drawing.Color.LightGray;

      this.ForeColor = System.Drawing.Color.Blue;

    }



    /// <summary>

    /// Accessor to set the background color of the control

    /// </summary>

    public override System.Drawing.Color BackColor 

    {

      get 

      {

        return base.BackColor;

      }

      set 

      {

        base.BackColor = value;

      }

    }



    /// <summary>

    /// Accessor to set the foreground color of the control

    /// </summary>

    public override System.Drawing.Color ForeColor 

    {

      get 

      {

        return base.ForeColor;

      }

      set 

      {

        base.ForeColor = value;

      }

    }



    /// <summary>

    /// Accessor to update the progress of the control

    /// </summary>

    public int PercentageOfProgress 

    {

      get 

      {

        return nProgress;

      }

      set 

      {

        // Make sure the progress doesn't have invalid values

        if (value > 100)

        {

          nProgress = 100;

        }

        else if (value < 0)

        {

          nProgress = 0;

        }

        else

        {

          nProgress = value;

        }



        // Calculate the percentage done if the progress > 0

        if (nProgress != 0)

        {

          nPercentOfProgress = nProgress / 5;

        }

      }

    }



    /// <summary>

    /// Renders the progress bar

    /// </summary>

    /// <param name="output"></param>

    protected override void Render(HtmlTextWriter output) 

    {



      // Create a table to render

      Table table      = new Table();

      TableRow row    = new TableRow();



      table.CellPadding  = 0;

      table.CellSpacing  = 0;

      table.BorderWidth  = 0;

      table.Width      = 100;



      // Add a row to the table

      table.Rows.Add(row);



      // Since we split the data into 20ths

      // we need a cell for each piece.

      // Another option is to use the GDI to 

      // create a graphic progress bar.

      for(int i = 0; i < 20; i++) 

      {

        TableCell td  = new TableCell();

        td.Width    = 5;

        td.Height    = 16;



        // If the count is less then the percent done 

        // then you need to set it to the fore color.

        // Otherwise the progress has not reached this 

        // cell and you need to set it to the back color.

        if (i < nPercentOfProgress)

        {

          td.BackColor = this.ForeColor;

        }

        else

        {

          td.BackColor = this.BackColor;

        }



        // Add the cell to our row

        row.Cells.Add(td);

      }



      // Add the table to the calling page

      this.Controls.Add(table);

      table.RenderControl(output);

    }

  }

}

Now you can create a new Web form and put your control in it.

How to Enable Access to Information in your HTTP Handlers

To make sure the popup-window can reach your information about the progress, you have to save it in the Application-state. The reason we use the application state to store the information is because Session state information is not available until the whole process is done. So in order to do this you need to create a unique key to make sure that every user doesn't get the same progress bar.

You will need to set this value when you are doing your processing. So in your aspx page that is doing the loading you can put something like this in the code behind page:




private void btnSubmit_Click(object sender, System.EventArgs e)

    {

      if(Page.IsValid)

      {

        // Start the proces

        for(int i = 0; i <= 100; i++) 

        {

          System.Threading.Thread.Sleep(300);

          

          // Save the progress in the Application-state with

          // a unique key for this session

          Application["progress_" + Session.SessionID] = i;

        }



        lblMsg.Text = "<h1>PROCESS FINISHED!!</h1>";

}

This will store the total percentage process in the application state. So in your Http Handler you can access that Application state variable like this:

    #region IHttpHandler Members

    public void ProcessRequest(HttpContext context)

    {

      HtmlTextWriter writer = new HtmlTextWriter(context.Response.Output);

      // Build the HTML for the popup

      writer.WriteFullBeginTag("html");

      writer.WriteFullBeginTag("body");

      writer.WriteFullBeginTag("head");

      writer.WriteFullBeginTag("title");

      writer.Write("Progress");

      writer.WriteEndTag("title");

      writer.WriteBeginTag("meta");

      writer.WriteAttribute("http-equiv","refresh");

      writer.WriteAttribute("content","1");

      writer.Write(HtmlTextWriter.TagRightChar);

      writer.WriteEndTag("head");

      writer.WriteFullBeginTag("body");

            

      int progress;



      // When the process is unknown in the Application-state, the process is 0

      if(context.Application["progress_" + context.Request.Params["id"]] == null)

        progress = 0;

      // Else this equals the int in the Application-state

      else

        progress = (int) context.Application["progress_" +

          context.Request.Params["id"]];



      // Create the progressbar

      Progress.ProgressBar pbProgress = new Progress.ProgressBar();

      pbProgress.ID = "ProgressBar";



      // Set the value of the progressbar

      pbProgress.PercentageOfProgress = progress;

      pbProgress.RenderControl(writer);



      writer.Write("<div align=\"center\">" + progress + "%</div>");



      // If the proces is finished,

      if(progress == 100) 

      {

        // Close the popup-window using JavaScript

        writer.WriteBeginTag("script");

        writer.WriteAttribute("language","javascript");

        writer.Write(HtmlTextWriter.TagRightChar);

        writer.Write("window.close();");

        writer.WriteEndTag("script");



        // DON'T FORGET to remove the variable from the Application-state,

        // otherwise it will exist 'forever'   

        context.Application.Remove("progress_" + context.Request.Params["id"]);

      }



      writer.WriteEndTag("body");

      writer.WriteEndTag("html");

    }

Registering Your HTTP Handlers with .NET

Registering HTTP Handlers with your .NET Web Application is extremely simple. All you have to do is add a new section to your <system.web> portion of your Web.Config file. The new section should look something like this:

<httpHandlers>
  <add verb="GET" path="ProgressBar.aspx" type="UploadProgressBar.CHttpUploadHandler, UploadProgressBar" validate="false" />
</httpHandlers>

Putting it all Together

This article includes the source files which you can download from here: ProgressBar.zip (21 KB). The Page that does the processing, in other words the page that you want to display the progress bar for, is called UploadForm.aspx. This page triggers a popup that loads ProgressBar.aspx. The HttpHandler that we specified in the Web.Config file catches any requests to ProgressBar.aspx and pipes them through the CHttpUploadHandler class. The process request in the class file prints a progress bar to the ProgressBar.aspx document.

Conclusion

I hope you enjoyed this article and you will find it usefull. If you have any questions please feel free to e-mail me at ruts@datausa.com. Happy Coding!

Close    To Top
  • Prev Article-Web Design:
  • Next Article-Web Design:
  • Now: Tutorial for Web and Software Design > Web Design > ASP > Web Design Content
    Photoshop Tutorial
     

    Special Effect

      3D Effect
      Photoshop Articles
    Programming Tutorial
     

    C/C++ Tutorial

      Visual Basic
      C# Tutorial
    Database Tutorial
     

    MySQL Tutorial

      MS SQL Tutorial
      Oracle Tutorial
    Geek Tutorial
     

    Blogging Tutorial

      RSS Tutorial
      Podcasting Tutorial
    Graphic Design Tutorial
      Coreldraw Tutorial
      Illustrator Tutorial
      3D Tutorials
    Webmaster Articles
     

    Domain Service

      Web Hosting
      Site Promotion
    Java Tutorial/ Articles
     

    Java Servlets

      JavaEE Tutorial
     

    JavaBeans Tutorial

    XML Tutorial/ Articles
     

    XML Style

      AJAX Tutorial
      XML Mobile
    Flash Tutorial/ Articles
     

    Flash Video

      Action Script
      Flash Articles
    OS Tutorial/ Articles
      Linux Tutorial
      Symbian Tutorial
      MacOS Tutorial
    Personal Tech
      Hardware Tutorial
      Software Tutorial
      Online Auction