In time, I hope to be able to look back on this day and think wow, was I ever that ignant? Something that has plagued me and many others in ASP.NET 1.x has been resolved (no pun intended) in 2.0, viz. a static framework method to resolve an application-relative URL into a server-relative URL. This is one of those problems that you feel like there must be a solution for, but maybe you just could never find it, or maybe you just didn't take the time because you created a solution that worked well enough.
In 1.x, on virtually every application I wrote, I ended up creating some utility method that would essentially do what the ~/ would do in a user control, which is equivalent to calling the ResolveUrl method. The main idea, of course, is that we need a URL that is valid, regardless of the context, regardless of whether or not the application is being run on a development machine in a virtual directory or on a production server off the root. Or maybe we just wanted to make it easy to change the virtual directory name--you know how fickle those users can be when it comes to what they want to see in the address bar! :)
So what did you do in 1.x? Specifically when you didn't have a readily-available control to call ResolveUrl on? If you're anything like me, DotNetNuke, or sundry others, you probably made some utility function that would squish the application path in front of the URL using the Request.ApplicationPath, if you could, or if you were really knowledgeable, the HttpRuntime.AppDomainAppVirtualPath property. (Shh, don't tell anyone.. apparently, I'm not that knowledgeable as I just had this pointed out to me by David Ebbo; I usually hacked that one as well, storing it in my Global class by ripping it off of HttpRequest or worse, specified it in the web.config... oog).
Well, even if you do get the application path, you still have to write a function to munge it with the relative URL to come up with what I call the server-relative URL (i.e., an URL that starts with /). Good grief! Couldn't they have a function to do this that is static (doesn't require a valid request context)!?
Never fear, in 2.0, we have a neat new utility class called VirtualPathUtility! You can read through the docs to figure out all the neat-o features, but the only one I particularly care about is ToAbsolute. This one is, as far as I can make out, the functional equivalent of ResolveUrl, so now I can resolve server-relative URLs from app-relative ones without needing a valid request context and without writing my own functoid for it. Woohoo! Note: I say "server-relative" because the URL is relative to the server root. For some reason, the MS folks call it "Absolute." To me, absolute would include the full URL, including server. I'm sure they had a good reason for it...
So that's it. No more messing about with all that garbage. Just declare all of your URLs using ~/, and call VirtualPathUtility.ToAbsolute to get a URL that should be valid regardless of your deployment environment. Too cool!
Edit: Forgot to give credit to David Ebbo on the Web Platforms and Tools Team at Microsoft for pointing out this new utility class to me. Thanks, David!
Disclaimer The opinions expressed herein are solely my own personal opinions, founded or unfounded, rational or not, and you can quote me on that.
Thanks to the good folks at dasBlog!
Copyright © 2008 J. Ambrose Little