Use Custom HTTP Handlers in Your ASP.NET Applications

An HTTP handler is the endpoint that responds to requests made by an ASP.NET Web application. The ASP.NET requests are mapped to HTTP handlers based on the type of file extension used. Each handler processes either an individual URL or groups of URL extensions within an application. If you have built an ASP.NET Web application, you've already taken advantage of HTTP handlers.

ASP.NET offers a few default HTTP handlers:

  • Page Handler (.aspx)—Handles Web pages
  • User Control Handler (.ascx)—Handles Web user control pages
  • Web Service Handler (.asmx)—Handles Web service pages
  • Trace Handler (trace.axd)—Handles trace functionality

As you can probably tell from the list, these handlers are pretty important to the normal operation of your ASP.NET Web applications. Without them, the Web pages wouldn't process, user controls wouldn't display, and your Web service calls wouldn't respond.

This article explores the built-in ASP.NET HTTP handlers and the value they provide. It mainly demonstrates how to create a custom HTTP handler and explains why you may want to create one. The included examples are built in Visual Studio 2005 and Microsoft .NET 2.0.

Creating a Custom HTTP Handler

You may choose to create a custom HTTP handler for any number of reasons. For instance, when you want special handling within your Web applications, you could add such handling through file name extensions assigned to custom HTTP handlers. Two other relatively common solutions for which you could create handlers are the following:

  • Dynamic image creator—Use the System.Drawing classes to draw and size your own images.
  • RSS—Create a handler that responds with RSS-formatted XML. This would allow you to add RSS feed capabilities to your sites.

As with many other areas of .NET, you override interfaces to generate HTTP custom handlers. You implement the IHttpHandler interface to create a synchronous handler and the IHttpAsyncHandler interface to create an asynchronous handler. The interfaces require you to implement the ProcessRequest method and the IsReusable property. The ProcessRequest method handles the actual processing for requests made, while the Boolean IsReusable property specifies whether your handler can be pooled for reuse (to increase performance) or whether a new handler is required for each request.

The .ashx file extension is reserved for custom handlers. If you create a custom handler with a file name extension of .ashx, it will automatically be registered within IIS and ASP.NET. If you choose to use an alternate file extension, you will have to register the extension within IIS and ASP.NET. The advantage of using an extension other than .ashx is that you can assign multiple file extensions to one handler.

Custom HTTP Handler Sample Code

The following example demonstrates how to create and register a custom HTTP handler to generate dynamic pie chart images using Microsoft .NET 2.0. Because I'm all about reuse, the example reuses sample code from a prior article on "Creating Simple Charts and Graphs." It pulls in the code to have a custom HTTP handler generate an image containing a pie chart. Also, it uses the file extension .piechart to indicate that it produces a piechart. By following this example, you use the query string to convey the width, height, and points to plot.

First, create a new 2.0-based Web project and then add a PieChartHandler class to the App_Code ASP.NET folder. (Note that ASP.NET 2.0 made HTTP handlers even easier than before. In prior ASP.NET versions, the App_Code ASP.NET folder didn't exist. Once you created an .ashx file, you couldn't have included it in your project or debugged it.) Use the following sample code for the PieChartHandler class:

using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Web;

public class PieChartHandler : IHttpHandler {

   public void ProcessRequest (HttpContext context) 
   {
   /* Start of code reuse */
context.Response.ContentType = "image/png";

// Read chart setup information
   string chartType = context.Request.QueryString["chartType"];
   int height = Convert.ToInt32(context.Request.QueryString["height"]);
   int width = Convert.ToInt32(context.Request.QueryString["width"]);
   Bitmap StockBitMap;
   Color bgColor = Color.FromArgb(255, 253, 244);
   MemoryStream memStream = new MemoryStream();

   switch (chartType)
   {
      default:
         // Determine the number of points given and read the values
         int numPoints = 1;
         while (context.Request.QueryString["P" +
                numPoints.ToString()] != null)
             numPoints++;
         decimal[] vals = new Decimal[numPoints];
         for (int i = 0; i < numPoints; i++)
            vals[i] = Convert.ToInt32(
            context.Request.QueryString["P" + i.ToString()]);

         PieChart pie = new PieChart();
         StockBitMap = pie.Draw(bgColor, width, height, vals);
         break;
      }

      // Render BitMap Stream Back To Client
      StockBitMap.Save(memStream, ImageFormat.Png);
      memStream.WriteTo(context.Response.OutputStream);
      /* End of code reuse */
   }

   public bool IsReusable 
   {
      get {
         return false;
      }
   }

}

/* Start of code reuse */
public class PieChart
{
   public Bitmap Draw(Color bgColor, int width, int height,
          decimal[] vals)
   {
      // Create a new image and erase the background
      Bitmap bitmap = new Bitmap(width, height,
                                 PixelFormat.Format32bppArgb);
      Graphics graphics = Graphics.FromImage(bitmap);
      SolidBrush brush = new SolidBrush(bgColor);
      graphics.FillRectangle(brush, 0, 0, width, height);
      brush.Dispose();

      // Create brushes for coloring the pie chart
      SolidBrush[] brushes = new SolidBrush[10];
      brushes[0] = new SolidBrush(Color.Yellow);
      brushes[1] = new SolidBrush(Color.Green);
      brushes[2] = new SolidBrush(Color.Blue);
      brushes[3] = new SolidBrush(Color.Cyan);
      brushes[4] = new SolidBrush(Color.Magenta);
      brushes[5] = new SolidBrush(Color.Red);
      brushes[6] = new SolidBrush(Color.Black);
      brushes[7] = new SolidBrush(Color.Gray);
      brushes[8] = new SolidBrush(Color.Maroon);
      brushes[9] = new SolidBrush(Color.LightBlue);

      // Sum the inputs to get the total
      decimal total = 0.0m;
      foreach (decimal val in vals)
         total += val;

      // Draw the pie chart
      float start = 0.0f;
      float end   = 0.0f;
      decimal current = 0.0m;
      for (int i = 0; i < vals.Length; i++)
      {
         current += vals[i];
         start = end;
         end = (float)(current / total) * 360.0f;
         graphics.FillPie(brushes[i % 10], 0.0f, 0.0f, width,
                          height, start, end - start);
      }

      // Clean up the brush resources
      foreach (SolidBrush cleanBrush in brushes)
         cleanBrush.Dispose();

      return bitmap;
   }
   /* End of code reuse */
}

Registering a custom handler that does not use the .ashx extension is fairly straightforward. As you may have guessed, you do it through a section of the web.config file by adding an httpHandlers element. An example registration might look like the following:

<configuration>
   <system.web>
      <httpHandlers>
         <add verb="*" path="*.piechart" type="PieChartHandler"/>
      </httpHandlers>
   </system.web>
</configuration>

Now, run the project and then use the URL http://localhost:1096/SampleSite/foo.piechart?chartType=pie&width=200&height=200&P1=20&P2=15&P3=55&P4=82&P5=102&P6=6 to view the results (see Figure 1). Note the ":1096" portion of the URL. Visual Studio 2005 provides a Web server for debugging Web applications, so you don't need to have a Web server on your development machine anymore. That is the configuration this example uses, which results in ":1096" being added to the URL. It will differ depending upon your personal configuration.

Figure 1. Sample Pie Chart Output

Now That You've Covered the Basics

Now you've explored the basic HTTP handlers that are built in to ASP.NET, and you've seen how easy it is to generate a custom HTTP handler that generates an image containing a pie chart. An advanced HTTP handler solution to consider—possibly a future column if there's interest—would be using an HTTP handler factory through the IHttpHandlerFactory interface. This would allow you extremely granular control over the processing of a request by instantiating the desired handler based on runtime conditions.

Future Columns

The next column has yet to be determined. If you have something in particular that you would like to see explained, please e-mail me at mstrawmyer@crowechizek.com.



About the Author

Mark Strawmyer

Mark Strawmyer is a Senior Architect of .NET applications for large and mid-size organizations. He specializes in architecture, design and development of Microsoft-based solutions. Mark was honored to be named a Microsoft MVP for application development with C# for the fifth year in a row. You can reach Mark at mark.strawmyer@crowehorwath.com.

Comments

  • There are no comments yet. Be the first to comment!

Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • It's time high-level executives and IT compliance officers recognize and acknowledge the danger of malicious insiders, an increased attack surface and the potential for breaches caused by employee error or negligence. See why there is extra emphasis on insider threats.

  • Today's competitive marketplace requires the organization to frequently release and deploy applications at the pace of user demands, with reduced cost, risk, and increased quality. This book defines the basics of application release and deployment, and provides best practices for implementation with resources for a deeper dive. Inside you will find: The business and technical drivers behind automated application release and deployment. Evaluation guides for application release and deployment solutions. …

Most Popular Programming Stories

More for Developers

Latest Developer Headlines

RSS Feeds