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!