I've started to work a bit with master pages for an mvc site and I've come across a question. When I link in a stylesheet on the master page it seems to update the path to the sheet correctly. That is in the code I have

<link href="../../Content/Site.css" rel="stylesheet" type="text/css" />

but looking at the source once the page is fed to a browser I get

<link href="Content/Site.css" rel="stylesheet" type="text/css" />

which is perfect. However the same path translation doesn't seem to work for script files.

<script src="../../Content/menu.js" type="text/javascript"></script>

just comes out as the same thing. It still seems to work on a top level page but I suspect that is just the browser/web server correcting my error. Is there a way to get the src path to be globbed too?


Use this instead:

<link href="~/Content/Site.css" rel="stylesheet" type="text/css" />
That won't work - the ~/ is replaced server side, so you need to add a runat="server" or wrap the location in a ResolveClientUrl
+1  A: 

Make an extension method. Here's a method:

public static string ResolveUrl(this HtmlHelper helper, string virtualUrl)
    HttpContextBase ctx = helper.ViewContext.HttpContext;
    string result = virtualUrl;

    if (virtualUrl.StartsWith("~/"))
        virtualUrl = virtualUrl.Remove(0, 2);

        //get the site root
        string siteRoot = ctx.Request.ApplicationPath;

        if (!siteRoot.EndsWith("/"))
            siteRoot += "/";

        result = siteRoot + virtualUrl;
    return result;

You can then write your script ref like:

<script type="text/javascript" src="<%= Html.ResolveUrl("~/Content/menu.js")%>"></script>

or you can use BASE tag in you HEAD section of page. All you links then are relative to location entered in "base" tag, and you don't have to use "../../" and "~" stuff. Except links in CSS files (background url,etc), where links are relative to location of css file.

+2  A: 
<script src="<%= ResolveClientUrl("~/Content/menu.js") %>" type="text/javascript"></script>
Shawn Miller
Awesome, this is EXACTLY what has been missing in web pages since their inception
If this is in the <head> you may be better off using <%# and calling databind instead. <%= stops you from dynamically adding to the container, something lots of web controls do automatically