Path resolution in ASP.NET

One thing I’ve always thought that ASP.NET doesn’t do a great job of is handling resource paths. For example, lets say on your development box, you have a website hosted under the virtual directory “MyProject”, such that you browse to http://localhost/MyProject/ to go to the home page. Lets also say that when you deploy the website to an external domain, it falls into the domain root, so instead you go to http://myproject.com/ to see your home page.

Sound familiar? The real problem then comes when you try and define a resource (e.g. a javascript file) using a relative path:

<script
    type="text/javascript"
    src="/Scripts/jquery.js">

This will work fine and dandy when you deploy the website, however on your local machine it will be looking for jquery at the path http://localhost/Scripts/jquery.js” – which more than likely isn’t going to work.

To get around this problem, I wrote a quick helper method called “Locate”, which I find myself reusing time and time again between websites. More often than not, I put it into a static class called “SiteManager” which basically just contains a bunch of helper functions relevant to the current website. Here’s the method:

/// <summary>
/// Resolves the path to a URL
/// </summary>
/// <param name="url">The path to be resolved, relative to the
/// application root</param>
/// <param name="formatArgs">String formatting arguments</param>
/// <returns>The URL</returns>
static public string Locate(string url, params object[] formatArgs)
{
    if (String.IsNullOrEmpty(url))
        url = "/";

    if (formatArgs != null && formatArgs.Length > 0)
        url = String.Format(url, formatArgs);

    HttpContext context = HttpContext.Current;
    return String.Concat(
        context.Request.ApplicationPath,
        !url.StartsWith("/") ? "/" : String.Empty,
        url);
}

To use the method, you simply change your script declaration (or whatever resource you’re trying to find) as follows:

<script
    type="text/javascript"
    src="<%= SiteManager.Locate("/Scripts/jquery.js") %>">
</script>

You’ll also notice that it supports string formatting – so even though it would be pointless in this particular example, you could, if you preferred, do something like this:

<script
    type="text/javascript"
    src="<%= SiteManager.Locate("/Scripts/{0}.js", "jquery") %>">
</script>

In both instances, this will resolve the URL in your output document using the current application path –

  • http://localhost/MyProject/Scripts/jquery.js on your local machine; and
  • http://myproject.com/Scripts/jquery.js on the web server.

Enjoy!

Posted in Asp.Net, C# by Gerrod at January 14th, 2010.

5 Responses to “Path resolution in ASP.NET”

  1. Drew says:

    The url would work in both production and development if you changed the href to “Scripts/jquery.js” as well.

  2. Drew says:

    Or you could always serve jquery from google or microsoft’s CDN.

  3. Gerrod says:

    Hey Drew – using “scripts/jquery” would only work if the file that is loading the script is in the root of the website. If your page was “mywebsite/accounts/default.aspx” it would look for a “scripts” folder under the “accounts” folder.

    And yes, you’re absolutely right about serving jquery from Microsoft or Google, but this can be applied for any resource – your own javascript files or images, for example…

  4. Drew says:

    Ah yes I follow now. If your head tag is set to “runat=server” you can you the “~” key to resolve the path from the application root as well. Or using master pages could eliminate the need for it as well.

  5. Nelson says:

    Actually, using master pages won’t resolve it, because the path is still relative to the derived pages. If you have derived pages in several subfolders it’s nearly impossible to get it working. With runat=server, I think I have had ASP.NET throw a parsing error, probably because it doesn’t know what to do with the actual JavaScript/CSS/whatever content. I may be wrong, though…

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Quickduck logo