Working with ASP.Net HTTPHandlers
ASP.Net is one of the most capable platforms for web development in existence today, and has everything that a dynamic website needs to grow and develop. A lot o ASP.Net functionality is built using the core features that .Net provides. A great example is ASP.Net MVC which is built over the existing ASP.Net insfrastructure but radically different from the classic ASP.Net programming model.
Imagine building something like ASP.Net MVC? Maybe not so complex, but something interesting that would handle a specialized extension and serve up some data with some special processing. With ASP.Net’s HTTPHandlers you can do that.
How Do HTTPHandlers Work
An HTTPHandler is the mechanism used by ASP.Net to process any file that is requested from it. In fact ASP.Net’s native .aspx pages are delivered using the same technology. When a HTTP Handler is registered with ASP.Net (using the web.config file), and appropriate settings are made in IIS then your server will start executing your HTTP Handler whenever a file of the extension you specified is requested from the server.
This lets you manipulate the output and return specially formatted data that can be displayed in a viewer friendly manner.
ASP.Net uses the ISAPI (Internet Server Application Programming Interface) to the connect to IIS and process the requests. The HTTPHandler is the shortest connection between IIS and ASP.Net. It does not carry any baggage of a page-request, headers or mime-types, so it can be used to deliver high performance data in any format – binary or html.
Setting up a HTTPHandler
Let’s consider an example scenario. Assume we’ve got a bunch of CSV files containing contacts data on our server and we want to create a Handler that lets the visitors view the CSV files in a tabular format. All the files on the server have the extension ‘.csv’. Let’s create a handler which does the job.
Step 1: Create a Class
Create a new class to contain our handler code. Let’s call this ‘Handler’.
Step 2: Alter the Web.Config file
We need to make the appropriate entries in the Web.Config file of our project so that ASP.Net will call our handler instead of sending the requested file to the browser.
<configuration>
<httpHandlers>
<addverb="*"path="*.csv"type="HTTPHandler.Handler, HTTPHandler"/>
</httpHandlers>
</configuration>
This will route all requests to a CSV file to our handler. Let’s understand how this works
Verb – Which type of HTTP Request will this handler consume. You can use the asterisk wildcard (‘*’) if you want to handle all requests, or you can set it up only for specific verbs like ‘GET, POST’.
Path – The extension you want to capture.
Type – the class and the namespace of your handler code.
Step 3: Set up the handler in IIS
We’ve already told ASP.Net to call our handler code when it gets a request for our extension, but before ASP.Net can do that, we need to tell IIS to send all requests for the files to ASP.Net.
--> Load IIS
--> Right Click on ‘Websites’->’Your Website’ and choose Properties
--> Select the ‘Home Directory’ tab and click ‘Configuration’
--> In the Executable Section put a reference to the ASP.Net ISAPI DLL (get the path from the .aspx Application Extension already present
--> In the Extension field put in your custom extension (we’ve filled .csv) and click OK.
Coding the HTTP Handler
Now that we’ve set up our HTTP handler, let’s code it and get it working.
The HTTP Hander class we created must implement the IHttpHandler interface. This is a simple interface with two functions:
- ProcessRequest
- IsReusable
n
Th IsReusable function decides whether the HTTP Handler instance can be used by multiple requests. This will return true in most cases.
ProcessRequest is the function that we are primarily concerned with. Our main code will reside here, and we will process the request, returning desired data from this function. Here’s the code we have written.
public class Handler : IHttpHandler
{
#region IHttpHandler Members
public bool IsReusable
{
get { return true; }
}
public void ProcessRequest(HttpContext context)
{
string file = context.Request.Url.Segments.Last<string>(); //Get the name of the page requested
if (file.Substring(file.Length - 3).ToUpper() == "CSV") //Does this page have .csv extension
{
string txt = System.IO.File.ReadAllText(context.Server.MapPath(context.Request.Url.AbsolutePath)); //Load the file and read the text
string[] lines = txt.Split(Environment.NewLine.ToCharArray()); //Split the file on the basis of lines
HttpResponse res = context.Response;
GetHeader(res); //Add the HTML header
res.Write("<body>");
res.Write("<table class='tbl'>");
int iCount = 0;
foreach (string line in lines) //Loop through each line of the csv and show it
{
res.Write("<tr>"); //Start a new row
if (!string.IsNullOrEmpty(line)) //Skip empty lines
{
string[] cols = line.Split(','); //Split on commas
foreach (string col in cols)
{
res.Write("<td>"); //Start a new column
if (iCount == 0)
{
res.Write("<strong>"); //Make the headings bold (first item of the row)
res.Write(col.Trim()); //Write the contents of the column
res.Write("</strong>");
}
else
res.Write(col.Trim());
res.Write("<td>");
}
}
res.Write("</tr>");
iCount++;
}
//Close the HTML tags
res.Write("</table>");
res.Write("</body>");
res.Write("</html>");
}
}
///<summary>
/// Get the header for the HTML page
///</summary>
///<param name="res"></param>
private void GetHeader(HttpResponse res)
{
//Add the headers along with our little CSS
res.Write("<!DOCTYPE html>");
res.Write("<html>");
res.Write("<title>This is a CSV file</title>");
res.Write("<style type='text/css'>body{}.tbl{border:solid 1px gray;} .tbl td{border-bottom:solid 1px gray;padding:3px;}</style>");
res.Write("<head>");
res.Write("</head>");
}
#endregion
}
Here is the CSV Data that we’re processing in the sample project:
Name, Age, Phone Number
John Doe, 34, 2343434
John Smith, 23, 45080
Jane Doe, 45, 23555
Jane Smith, 65, 343444
Big Joe, 23, 3454533
Little Moe, 32, 545456
And this is the Output
We’ve written a complete web-page through code, including Doctype and HTML headers. While this is one possible use, you might be able to use it more often to return partial data of page, and binary data like custom images (ex., after you’ve watermarked them), etc.
If you read the code above you can see that our class Handler implements the interface IHttpHandler. Most of our code is in the ProcessRequest function.
Working with Context Object.
The ProcessRequest function gives us the HttpContext object (context), which has all the information we need to process the request and return the result. The HttpContext object has several objects like Request, Response, Session, Server, etc.
The Request object has details like the file requested, querystring, etc. You can also get additional information like request type, HTTP headers sent, etc., from this object.
The Server object has all your server information. In this example we use the MapPath function of the object to find the physical path of the file on the disk base on its Absolute URL path.
You can use the Session object to store any information that you want to manage on the server. The most popular usage is to keep user login information which can be used to make sure that your user is authorized to view the content they are requesting.
The Response object is used to send your data to the client. This data can be text, image, sound, video or any other file. You can set the mime-type to a suitable format depending on the data you send. If you are sending plain text or HTML content you can go with the default values. The function we use to send the data to the client is Response.Write(). You must have used this in your regular ASP.Net files earlier.
Conclusion
This concludes our little tutorial on HttpHandlers. Now you’re ready to use this powerful technique to serve custom and binary content to your visitors.
If you don’t need to serve data based on specific file formats, you can use ashx (HTML Handler) files to get the advantage of faster processing (no page-cycle) to serve custom content to your viewers. To do this you just need to create an ashx file and implement IHttpHandler. Your content will be available only when a visitor requests your ashx file.
If you want to download the "IHttpHandler Sample Project.zip" file for this article, please REGISTER first.
|