Friday, November 22, 2013

User-Freindly URLs for HttpHandlers

I was interested in implemented a cleaner URL scheme for an HttpHandler in ASP.NET. Out of the box it's pretty easy to set up an HttpHandler. Simply add a file with an ".ashx" extension and the @WebHandler directive and IIS will use the the Generic Web Handler to route traffic to your handler. The downside is that the handler has to end with ".ashx" and all parameters have to go on the querystring.

With the introduction of MVC, Microsoft built RESTful style routing functionality. I had read that with ASP.NET 4.0 they exposed this functionality so it could be used outside of MVC. I found a number of articles (here and here) on how I could set up custom routes to my handler. As I tried to follow the examples in the articles they all had more complexity than I needed to get going. I was eventually able to get it working but wished for a simpler example.

So I created a stripped down example. In the example below you access the site like http://example.com/quote/MSFT. URLs with /quote are routed to the handler and the next item in the URL is used as a parameter.
  1. Create a new 4.0 (or higher) empty ASP.NET website.
  2. Add an App_Code directory and custom HttpHandler like the following:
    /// 
    /// HTTP Handler to return raw HTML.
    /// 
    public class CustomHttpHandler : IHttpHandler {
    
      // This holds the additional parameters from the URL.
      public RouteData RouteData { get; set; }
    
      public void ProcessRequest(HttpContext context) {
        string symbol = RouteData.Values["symbol"] as string;
        context.Response.ContentType = "text/html";
        context.Response.Write("Stock symbol is " + symbol);
      }
    
      public bool IsReusable {
        get { return false; }
      }
    }
  3. Add the Global.asax file and in Application_Start add a route to the RouteTable. This takes an instance of a class that implements IRouteHandler.
     void Application_Start(object sender, EventArgs e) {
      RouteTable.Routes.Add("quote", new Route("quote/{symbol}", new CustomRouteHandler()));
      }
    
  4. Add the route handler class that implements IRouteHandler. This must return an instance of the HttpHandler you want the URL directed to.
    public class CustomRouteHandler : IRouteHandler {
      public CustomRouteHandler() {
      }
    
      public IHttpHandler GetHttpHandler(RequestContext requestContext) {
        var handler = new CustomHttpHandler();
        handler.RouteData = requestContext.RouteData; // Include the reference to the RouteData
        return handler;
      }
    }