Library tutorials & articles

Implementing HTTP Handlers in ASP.NET

Redirect, Transfer or Rewrite?

Earlier, we implemented a URL rewriting scheme; however, in some circumstances, you may wish to implement a Response.Redirect() or Server.Transfer() instead. One reason to do this is to forward from Default.aspx to another page, like Home.aspx. You may or may not want to do this "behind the scenes," but that is a decision for you to make yourself. As always, each option comes with its own set of pros and cons.

Redirects are essentially two GET (or POST) requests. The first request gets processed and then the Response.Redirect() sends a response back to the client with an HTTP 302 redirect command. This obviously causes a slight delay as the second request gets processed. Also, since the new URL is sent to the client, it won't be hidden. This clearly doesn't support URL beautification, which is the main reason most people implement handlers. Even though redirects won't solve your problems, they still play an important part in the overall solution and should be considered when developing your mapping solution.

Transfers, unlike redirects, keep control within the application; but, they are still treated as two requests. The difference is that instead of the client handling the HTTP 302 redirect command, the web server handles it. This means that any modules, as well as the handler, will be processed twice . There are three key things to remember when using transfers: (1) the Request object, and all of its properties and methods, will reflect the initial request (logical page) and not the physical page; (2) post-back will not work; and, (3) in order to use the transfer you have to have two handlers specified in the Web.config file. There might be a way to get the post-back to work, but I don't know what that would entail. Perhaps I will delve into the ASP.NET request process fully one day. As for the two handler issue, let me explain that in a bit more detail. As you may remember from above, you specified two handlers in the Web.config file. The reason for this is because after the Server.Transfer() is executed, ASP.NET will send the second request back through the handler. I'm not completely sure why this is a problem, but it is. So, to fix it, you need to have some way to identify what requests should be handled by ASP.NET's default handler and which should be handled by yours. I attacked this by putting all of my physical pages in a Pages directory. So, by re-adding the default handler to handle all requests to "*/Pages/*.aspx", we tell ASP.NET how to support each type of request. As I also mentioned before, this will fix the the "Error executing child request" error.

Rewrites provide the best performance because there is no back-tracking to re-handle requests. You simply change the URL and continue on with the request processing. Know that accessing the Request object will now reflect the new (physical) URL and you will not have access to the old (logical) URL. You can get around this by adding custom variables to the HttpContext, but that shouldn't be necessary for most situations.

To add support for redirects and transfers, we can simply change our Web.config file by prepending "redirect.", "transfer.", or "rewrite." to identify how we want the request handled. Then, update the IHttpHandler.ProcessRequest() method to treat them accordingly.

HttpHandler.ProcessRequest() Method

public void ProcessRequest(HttpContext context)
{
  // declare vars
  string requestedUrl;
  string targetUrl;
  int urlLength;

  // save requested, target url
  requestedUrl = context.Request.RawUrl;
  if ( requestedUrl.IndexOf("?") >= 0 )
    targetUrl = ConfigurationSettings.AppSettings[requestedUrl.Substring(0, requestedUrl.IndexOf("?"))];
  else
    targetUrl = ConfigurationSettings.AppSettings[requestedUrl];
  if ( targetUrl == null || targetUrl.Length == 0 )
    targetUrl = requestedUrl;

  // handle type 
  if ( targetUrl.StartsWith("redirect.") )
  {
    context.Response.Redirect(targetUrl.Substring(9));
  }
  else if ( targetUrl.StartsWith("transfer.") )
  {
    context.Server.Transfer(targetUrl.Substring(9));
  }
  else
  {
    // if type is specified, remove it
    if ( targetUrl.StartsWith("rewrite.") )
      targetUrl = targetUrl.Substring(8);

    // save target url length
    urlLength = targetUrl.IndexOf("?");
    if ( urlLength == -1 )
      urlLength = targetUrl.Length;

    // rewrite path
    context.RewritePath(targetUrl);
    IHttpHandler handler = PageParser.GetCompiledPageInstance(
    targetUrl.Substring(0, urlLength), null, context );
    handler.ProcessRequest(context);
  }
}

Conclusion

Well, congratulations on your first HTTP handler implementation. There is plenty of room for improvement, so try to think of how you can manage the mappings to add more than just a simple URL rewriting scheme. One thing that you might want to consider is a post-back processing component. Yes, post-back is handled by ASP.NET, but performance can be increased by removing that overhead. Anyway, my point is that there are a lot of things you can do to improve this simple implementation. I encourage you to add to this and let me know how well it works out for you. I'd be interested to hear some of the things people are doing with handlers. Good luck!

Comments

  1. 21 Nov 2007 at 12:24

    I haven't touched this since .NET 1.1. And, with IIS7, I'd say there's a better approach. I'll probably revisit this when I have some time to play with IIS7.

  2. 20 Nov 2007 at 05:45

    Did you ever find a better solution for the ActionLess form - for Url Rewriting ???

    Your post to experts exchange requires a subscriptin to read the answer...

     

    Cant I just get away with in NET 2.0 putting form id='myForm' Method=""

    I know it is malformed ...

  3. 01 Jun 2006 at 20:40

    You seem to have forgotten an important problem with your actionless form. I have discovered that this custom form will disable the validation controls. Now the onsubmit function for client side validation needs to be added back in. I found this post about the problem (http://www.experts-exchange.com/Web/Q_21842631.html), but am still wondering if there is not an easier way to fix this.

  4. 13 Mar 2005 at 21:15

    thank you very much. I am knew this posting and waiting for nothoing

  5. 01 Jan 1999 at 00:00

    This thread is for discussions of Implementing HTTP Handlers in ASP.NET.

Leave a comment

Sign in or Join us (it's free).

Michael Flanakin Michael Flanakin is a principal .NET software architect for the US Air Force and is the president of the Air Force .NET User Group, which serves .NET developers world-wide. Michael provides guidanc...

Related podcasts

Events coming up

  • Mar 15

    DevWeek 2010

    London, United Kingdom

    DevWeek is Europe’s leading independent conference for software developers, database professionals and IT architects, and features expert speakers on a wide range of topics, including .NET 4.0, Silverlight 3, WCF 4, Visual Studio 2010, REST, Windows Workflow 4, Thread Synchronization, ASP.NET 4.0, SQL Server 2008 R2, LINQ, Unit Testing, CLR & C# 4.0, .NET Patterns, WPF 4, F#, Windows Azure, ADO.NET, Entity Framework, Debugging, T-SQL Tips & Tricks, and more.

We'd love to hear what you think! Submit ideas or give us feedback