My Resume

  • My Resume (MS Word) My Resume (PDF)


Affiliations

  • Microsoft Most Valuable Professional
  • INETA Community Champion
  • Leader, NJDOTNET: Central New Jersey .NET User Group

Wednesday, August 1, 2007

Dummy Page Handler

My current project at Infragistics is revamping our entire redirect and tracking backend. Since we are dealing with redirects and rewrites, my tests naturally ventured into the realm of doing something to/with the current HttpContext. As anyone who's dealt with this can attest to, I had my fair share of difficulties along this road, but decided to blog about one problem and solution I thought might be particularly interesting and/or useful for anyone testing redirects.

My situation

I have a list of request URLs along with a corresponding redirect path for each of them. The project I'm working on is a library - it's meant to be used in a web site, but is not actually run as a standalone site. You can unit test with your favorite framework all you want, but at some point when you're dealing with redirection and the HttpContext, you're eventually going to want to try it out in a hosted environment. Using blog posts and code from Scott Hanselman and Paul Haack, I set myself up a nice little WebDev process and ran my integration tests within that. Everything worked great, except... RED BAR?!?

My redirection tests had failed. "404 Error" messages filled my Output box. Oh... yeah - using the hosted approach actually creates a website using physical files, just like any normal website. The fact that my integration test class library was the thing starting it up was irrelevant - it still expected the physical pages to exist and it wouldn't allow me to just redirect to any hypothetical path that I wanted to (even though my tests didn't really care whether the destination path actually existed or not - just that our response was redirected properly).

(Note: If you're not partial to my storytelling, you can just jump down to the Solution section below for what I eventually came up with.)

My first attempt at was a knee-jerk reaction: WebDev wanted a physical file? I'll give it one. So, I added "dummy.html" to my project and used TestWebServer.ExtractResource("dummy.html", destinationPath) before every request. Echk. This approach gave me a few reasons to feel uneasy: I now have an extra (rather meaningless) static file around to clutter up my project; I'm writing a file before EVERY request; and well, what if sometimes I actually wanted the 404 error to occur?

Onto attempt #2. Well, let's call it Attempt 1.1, because I didn't actually solve either of the last two issues, but that stupid extra file in my project was bugging me, so I replaced the call to ExtractResource("dummy.html", destinationPath) with CreateDummyPage(destinationPath). The CreateDummyPage() method did away with reading the dummy HTML page from the resources and just used a StringBuilder to populate the content... then wrote it to a file. But, like I said - this didn't really help fix my two other issues.

Solution

The solution ended up being ridiculously easy: write an HttpHandler to serve up dummy pages. The code ended up looking like below. Of course, you can boil this code down even more and simply use a string constant for the page content. But, as you can see, I wanted some kind of content on the page (to make sure the Handler itself was actually working, at the very least!).

using System;
using System.Text;
using System.Web;

namespace Infragistics.Guidance.Web

public class DummyPageServer : IHttpHandler
{
private string _PageTitle = "Dummy Web Page";

public bool IsReusable
{
get { return true; }
}

public void ProcessRequest(HttpContext context)
{
string body = String.Format("Requested path: {0}", context.Request.Path);
StringBuilder sb = new StringBuilder("<html>");
sb.AppendFormat("<head><title>{0}</title></head>", _PageTitle);
sb.AppendFormat("<body>{0}</body>", body);
sb.Append("</html>");
context.Response.ClearContent();
context.Response.Write(sb.ToString());
context.Response.End();
}
}
}







Then, you register the module like so:

Oh, but wait - what about my third concern from before? What if I don't want every .aspx request to be mocked up?? Just be more specific in the handler definitions, such as:

This approach seems to be working great for all of my tests so far. No more 404's - yay! I hope it can help with yours.