The conception, birth, and first steps of an application named Charlie

Subscribe: Atom or RSS

“You Are Here”

by Alister Jones (SomeNewKid)

Most ASP.NET applications have many files with the extension, .aspx. If the visitor requests the page about.aspx, then ASP.NET finds the file with that name, loads it up, executes it, and returns the HTML to the visitor. If the user requests the page contact.aspx, ASP.NET will find the file with that name, load it up, execute it, and return the HTML.

Some ASP.NET applications take a different approach. Rather than having a whole bunch of .aspx files, they have just one; typically it will be named default.aspx. What these applications do is use this single default.aspx file to “build” a dynamic page. So even if the visitor requests about.aspx, the application secretly redirects the request to default.aspx, and then builds the About page. If the visitor requests contact.aspx, the application again secretly redirects the request to default.aspx, and then builds the Contact page.

Charlie takes an altogether different approach. There is no .aspx file anywhere in the Charlie application. Instead, a page request will be handled by the WebHandler object, which exists only in memory. There is no corresponding .aspx file.

While I was in the early stages of developing Charlie, this approach worked fine. But as development progressed, this approach introduced two problems.

The first problem is that I could not get the Page.ParseControl method to work. Charlie kept complaining about its VirtualPathProvider. I told myself not to worry about this problem, because I was not yet at the stage of working with Charlie’s Interface layer. So I fudged my way around it.

Today I tried to introduce MasterPages to Charlie. The code is simple:

Page.MasterPageFile = "~/Templates/Default.master";

But Charlie was having none of it. Once again it started complaining about its VirtualPathProvider. This time, I could not fudge my way around the problem—I had to work it out.

If I created a new web application and put the above code into the code-file of an .aspx page, it worked fine. But if the “page” exists only in memory, as with Charlie, it does not work. I could not figure out why. The above code clearly states where the master page file is located, yet Charlie would not load it up. Why?

It turns out that a new feature of ASP.NET version 2.0 was throwing a spanner in the works. With ASP.NET version 1.1, a tilde-based path (such as “~/Templates”) would always resolve from the application’s root folder. This is precisely what the tilde means, so this was precisely the expected behaviour. However, with ASP.NET version 2.0, a tilde-based path may or may not resolve from the application’s root folder. ASP.NET version 2.0 allows an application to change how a tilde-based path is resolved. David Ebbo provides a weblog entry on how to do this. Ironically, I am the customer to whom David refers.

The problem for Charlie was that because its WebHandler object has no corresponding .aspx file, it did not know how to resolve a tilde-based path. In other words, Charlie did know know where this “virtual page” was located within the file system. The solution to the problem then was to tell the Charlie page, “You are here.”

Page.AppRelativeVirtualPath = @"~/";

This tells Charlie to consider that its virtual page is located within the application’s root folder. With that single line of code, Charlie has stopped complaining about its VirtualPathProvider. And I have stopped swearing at Charlie—at least for the time being.

by Alister Jones | Next up: A Dirty Sheet of Paper

0 comments

----