ASP.NET

Generic Handlers (ASHX Files)

Just as ASPX files can be compiled on the fly (just-in-time), so can handlers. Generic handlers have an extension of ASHX. They're equivalent to custom handlers written in C Sharp or Visual Basic.NET in that they contain classes that fully implement IHttpHandler. They're convenient in the same way ASPX files are convenient. You simply surf to them and they're compiled automatically.

The following example illustrates the CustomFormHandler implemented as a "generic handler."

Writing a Generic Handler

  1. Add a "generic" handler to the Web site. Go to the Solution Explorer, right-click on the CustomHandler Web site node and select Add New Item. Select Generic Handler from the templates. Name the handler CustomFormHandler.ashx:

    Graphic
  2. Visual Studio generates a handler that looks like this. It includes a stubbed-out Process[[<img src="images/shy.gif"/>]]Request method and IsReusable property.

    <%@ WebHandler Language="C#" %>
    
    using System.Web;
    
    public class CustomFormHandler : IHttpHandler {
    
        public void ProcessRequest (HttpContext context) {
    
            context.Response.ContentType = "text/plain";
            context.Response.Write("Hello World");
        }
    
        public bool IsReusable {
            get {
                return false;
            }
        }
    }
    
  3. Borrow the code from the earlier example to implement the handler. Replace the stubbed-out method and property with real implementations.

    <%@ WebHandler Language="C#" %>
    using System.Web;
    public class CustomFormHandler : IHttpHandler {
    
        public void ProcessRequest (HttpContext context) {
            ManageForm(context);
        }
    
        public void ManageForm(HttpContext context)
        {
            context.Response.Write("<html><body><form>");
    
            context.Response.Write(
              "<h2>Hello there. What's cool about .NET?</h2>");
            context.Response.Write("<select name='Feature'>");
            context.Response.Write("<option> Strong typing</option>");
            context.Response.Write("<option> Managed code</option>");
            context.Response.Write("<option> Language agnosticism</option>");
            context.Response.Write("<option> Better security model</option>");
            context.Response.Write(
               "<option> Threading and async delegates</option>");
            context.Response.Write("<option> XCOPY deployment</option>");
            context.Response.Write(
               "<option> Reasonable HTTP handling framework</option>");
            context.Response.Write("</select>");
            context.Response.Write("</br>");
           context.Response.Write(
               "<input type=submit name='Lookup' value='Lookup'></input>");
            context.Response.Write("</br>");
            if (context.Request.Params["Feature"] != null)
            {
                context.Response.Write("Hi, you picked: ");
                context.Response.Write(context.Request.Params["Feature"]);
                context.Response.Write(" as your favorite feature.</br>");
            }
    
            context.Response.Write("</form></body></html>");
        }
        public bool IsReusable
        {
            get
            {
                return false;
            }
        }
    }
    
  4. Browse to the CustomFormHandler.ashx file. It should work in just the same way as the handlers implemented in CustomFormHandler.cs and CustomFormHandler.VB, as shown in the following graphic:

    Graphic

The advantage of using the generic handler is twofold. First, it's usually much more convenient to generate a simple handler than it is to create a whole new assembly to handle the request. Second, you don't need to run interference with either Web.Config or with IIS. That is, Web.Config and IIS already understand what to do about files with the extension of .ashx. Installing ASP.NET places those when mapping into IIS.

However, ASHX files have the same limitations as ASPX and ASCX files in terms of their place in an ASP.NET project. Simple generic handlers go with the project. That is, for the handler to work, it must accompany the whole project. Alternatively, custom handlers deployed as separate assemblies may be deployed and shared among the enterprise as Global Assembly assemblies (that is, strongly named assemblies placed in the Global Assembly Cache).