Masterpage CSS link can't resolve ~

Darth Pseudonym picture Darth Pseudonym · Nov 1, 2011 · Viewed 8.2k times · Source

I'm working on a web interface in C# ASP.net. If it matters, I'm using XHTML 1.0 Transitional.

This website has a masterpage thing going, and that's where the problem came in. When I used a real absolute path for the CSS link in the header, everything was fine. But then when I tried to switch it to tilde notation, all the styling broke.

Here's a fragment of the original master page, which worked fine:

<head>
    <title>Account Information</title>
    <link href="/css/main.css" rel="stylesheet" type="text/css" />
</head>
<body>
...
</body>

But then we found out that this account thing is going to be an application that doesn't live on the server root, so we had to make changes.

<head>
    <title>Account Information</title>
    <link runat="server" href="~/css/main.css" rel="stylesheet" type="text/css" />
</head>
<body>
...
</body>

Now, those same changes (adding runat="server" and a tilde) worked just FINE everywhere else in the page, but this one didn't. When I looked at the output, it was not resolving the tilde, so the link was actually pointing at "myserver.net/~/css/main.css", which obviously isn't going to work.

Next I tried using ResolveURL, like so:

<link runat="server" href="<% =ResolveURL("~/css/main.css") %>" rel="stylesheet" type="text/css" />

Visual Studio wouldn't even compile that. It didn't even know what ResolveURL meant. (As a test, I stuck the same code several other places, including the page title right there next to the link tag, and it worked fine everywhere else!)

I did eventually get it to work by giving the link an ID and setting the href in the code-behind:

--Master page--
<link id="StyleLink" runat="server" rel="stylesheet" type="text/css" />

--Masterpage codebehind file--
StyleLink.Attributes.Add("href", ResolveUrl("~/css/main.css"));

But I'm left wondering why I had to spend two hours fighting with this. Why didn't the standard ~ notation work in the first place? I googled around for a while but I couldn't find anything particularly relevant; the closest I could find was a discussion of ~ notation failing when it was in a sub-master page.

Answer

Graham picture Graham · Nov 2, 2011

This works in the Master Page in front of me right now:

<head runat="server">
     <link runat="server" href="~/styles/main.css" rel="stylesheet" type="text/css" />
</head>

For a Page in the root of the application, this translates out to the HTML as this:

<link href="styles/main.css" rel="stylesheet" type="text/css" />

For a Page in a folder off the root, here's what it looks like:

<link href="../styles/main.css" rel="stylesheet" type="text/css" />

(Both pages use that Master, obviously)


Alternative approach

Store the path to the CSS file in the web config, and alter it upon deployment.
You can even use Web Config Transformations to change it automatically based on the build type.