Microsoft ASP.NET 3.5 : Writing HTTP Handlers (part 3) - The Picture Viewer Handler

- Free product key for windows 10
- Free Product Key for Microsoft office 365
- Malwarebytes Premium 3.7.1 Serial Keys (LifeTime) 2019
5/17/2012 3:53:02 PM

The Picture Viewer Handler

Let’s examine another scenario that involves custom HTTP handlers. Thus far, we have explored custom resources and realized how important it is to register any custom extensions with IIS.

To speed up processing, IIS claims the right of personally serving some resources that typically form a Web application without going down to a particular ISAPI extension. The list includes static files such as images and HTML files. What if you request a GIF or a JPG file directly from the address bar of the browser? IIS retrieves the specified resource, sets the proper content type on the response buffer, and writes out the bytes of the file. As a result, you’ll see the image in the browser’s page. So far so good.

What if you point your browser to a virtual folder that contains images? In this case, IIS doesn’t distinguish the contents of the folder and returns a list of files, as shown in Figure 4.

Figure 4. The standard IIS-provided view of a folder.

Wouldn’t it be nice if you could get a preview of the contained pictures, instead?

Designing the HTTP Handler

To start out, you need to decide how you would let IIS know about your wishes. You can use a particular endpoint that, appended to a folder’s name, convinces IIS to yield to ASP.NET and provide a preview of contained images. Put another way, the idea is binding our picture viewer handler to a particular endpoint—say, folder.axd.A fixed endpoint for handlers doesn’t have to be an existing, deployed resource. You make the folder.axd endpoint follow the folder name, as shown here:

The handler will process the URL, extract the folder name, and select all the contained pictures.


In ASP.NET, the .axd extension is commonly used for endpoints referencing a special service. Trace.axd for tracing and WebResource.axd for script and resources injection are examples of two popular uses of the extension. In particular, the Trace.axd handler implements the same logic described here. If you append its name to the URL, it will trace all requests for pages in that application.

Implementing the HTTP Handler

The picture viewer handler returns a page composed of a multirow table showing as many images as there are in the folder. Here’s the skeleton of the class:

class PictureViewerInfo
    public PictureViewerInfo() {
        DisplayWidth = 200;
        ColumnCount = 3;
    public int DisplayWidth;
    public int ColumnCount;
    public string FolderName;

public class PictureViewerHandler : IHttpHandler
    // Override the ProcessRequest method
    public void ProcessRequest(HttpContext context)
        PictureViewerInfo info = GetFolderInfo(context);
        string html = CreateOutput(info);

        // Output the data
        context.Response.Write("Picture Web Viewer");
    // Override the IsReusable property
    public bool IsReusable
        get { return true; }


Retrieving the actual path of the folder is as easy as stripping off the folder.axd string from the URL and trimming any trailing slashes or backslashes. Next, the URL of the folder is mapped to a server path and processed using the .NET Framework API for files and folders:

private ArrayList GetAllImages(string path)
    string[] fileTypes = { "*.bmp", "*.gif", "*.jpg", "*.png" };
    ArrayList images = new ArrayList();
    DirectoryInfo di = new DirectoryInfo(path);
    foreach (string ext in fileTypes)
        FileInfo[] files = di.GetFiles(ext);
        if (files.Length > 0)
    return images;

The DirectoryInfo class provides some helper functions on the specified directory; for example, the GetFiles method selects all the files that match the given pattern. Each file is wrapped by a FileInfo object. The method GetFiles doesn’t support multiple search patterns; to search for various file types, you need to iterate for each type and accumulate results in an array list or equivalent data structure.

After you get all the images in the folder, you move on to building the output for the request. The output is a table with a fixed number of cells and a variable number of rows to accommodate all selected images. The image is not downloaded as a thumbnail, but it is more simply rendered in a smaller area. For each image file, a new <img> tag is created through the Image control. The width attribute of this file is set to a fixed value (say, 200 pixels), causing most modern browsers to automatically resize the image. Furthermore, the image is wrapped by an anchor that links to the same image URL. As a result, when the user clicks on an image, the page refreshes and shows the same image at its natural size.

string CreateOutputForFolder(PictureViewerInfo info)
    ArrayList images = GetAllImages(info.FolderName);
    Table t = new Table();

    int index = 0;
    bool moreImages = true;
    while (moreImages)
        TableRow row = new TableRow();
        for (int i = 0; i < info.ColumnCount; i++)
            TableCell cell = new TableCell();

            // Create the image
            Image img = new Image();
            FileInfo fi = (FileInfo)images[index];
            img.ImageUrl = fi.Name;
            img.Width = Unit.Pixel(info.DisplayWidth);

            // Wrap the image in an anchor so that a larger image
            // is shown when the user clicks
            HtmlAnchor a = new HtmlAnchor();
            a.HRef = fi.Name;

            // Check whether there are more images to show
            moreImages = (index < images.Count);
            if (!moreImages)


You might want to make the handler accept some optional query string parameters, such as width and column count. These values are packed in an instance of the helper class PictureViewerInfo along with the name of the folder to view. Here’s the code to process the query string of the URL to extract parameters if any are present:

PictureViewerInfo info = new PictureViewerInfo();
object p1 = context.Request.Params["Width"];
object p2 = context.Request.Params["Cols"];
if (p1 != null)
    Int32.TryParse((string)p1, out info.DisplayWidth);
if (p2 != null)
    Int32.TryParse((string)p2, out info.ColumnCount);

Figure 5 shows the handler in action.

Figure 5. The picture viewer handler in action with a given number of columns and width.

Registering the handler is easy too. You just add the following script to the web.config file:

<add verb="*" path="folder.axd"
    type="Core35.Components.PictureViewerHandler,Core35Lib" />

You place the assembly in the GAC and move the configuration script to the global web.config to extend the settings to all applications on the machine.

Other -----------------
- Microsoft ASP.NET 3.5 : HTTP Handlers and Modules - Quick Overview of the IIS Extensibility API
- Programming WCF Services : Queued Services - The HTTP Bridge
- Microsoft ASP.NET 4 : Ajax - Extender Controls (part 2) - A Modal Pop-up Dialog-Style Component
- Microsoft ASP.NET 4 : Ajax - Extender Controls (part 1) - The AutoComplete Extender
- Mobile Handheld Devices : DATA SYNCHRONIZATION
- Mobile Handheld Devices : MEMORY, STORAGE AND BATTERIES
- LINQ to Objects : How to Return Elements When the Result Is a Sequence (Select Many)
- LINQ to Objects : How to Change the Return Type (Select Projection)
- A Technical Overview of the Mobile Web : OTHER MOBILE TECHNOLOGIES
- A Technical Overview of the Mobile Web : THE MOBILE NETWORK
- Programming WCF Services : The Response Service (part 4) - Transactions
- Programming WCF Services : The Response Service (part 3) - Queued Service-Side Programming & Response Service-Side Programming
- Programming WCF Services : The Response Service (part 2) - Client-Side Programming
- Programming WCF Services : The Response Service (part 1) - Designing a Response Service Contract
- Programming WCF Services : Queued Versus Connected Calls - Requiring Queuing
- Programming WCF Services : Queued Services - Playback Failures
- DotNetNuke Skinning : Package and Deploy
- Unit Testing in Visual Studio 2010 (part 2) - Running a battery of tests
- Unit Testing in Visual Studio 2010 (part 1) - Creating unit tests
- Microsoft ASP.NET 3.5 : AJAX-Enabled Web Services - Remote Calls via Page Methods
Top 10
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Finding containers and lists in Visio (part 2) - Wireframes,Legends
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Finding containers and lists in Visio (part 1) - Swimlanes
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Formatting and sizing lists
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Adding shapes to lists
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Sizing containers
- Microsoft Access 2010 : Control Properties and Why to Use Them (part 3) - The Other Properties of a Control
- Microsoft Access 2010 : Control Properties and Why to Use Them (part 2) - The Data Properties of a Control
- Microsoft Access 2010 : Control Properties and Why to Use Them (part 1) - The Format Properties of a Control
- Microsoft Access 2010 : Form Properties and Why Should You Use Them - Working with the Properties Window
- Microsoft Visio 2013 : Using the Organization Chart Wizard with new data
- First look: Apple Watch

- 3 Tips for Maintaining Your Cell Phone Battery (part 1)

- 3 Tips for Maintaining Your Cell Phone Battery (part 2)
programming4us programming4us