Skip navigation.

Free Apress Book On Web ServicesAll recent postsInitialize Page Titles from Site Map

More on URL Rebasing in Master Pages

Master pages are strange beasts. Scott Guthrie hinted earlier that there was no need for my BaseURL property to assist with proper linking to external CSS and JavaScript files. The runtime does its magic by adjusting URLs in the page head. However, it appears, the magic misfires at times.

A sample project

Suppose we have a simple project with two style sheets and a single web form. My master page has the following markup in its <head>:

<style type="text/css">
   @import '../css/screen.css';
</style>
<link type="text/css" rel="stylesheet" href="../css/print.css"/>

Note: the path to both stylesheets is relative to the master page location.

When I run default.aspx, the screen.css stylesheet isn’t applied. What’s wrong with the rendered markup:

<style type="text/css">
    @import '../css/screen.css';
</style>
<link type="text/css" rel="stylesheet" href="css/print.css" />

You see that the path to print.css got properly rebased (“adjusted”, if you will), but the <style> section was left untouched. My guess is the runtime knows how to parse only primitives like <link>.

There are two workarounds for this. You can use a property similar to my BaseURL or, as Dave Griffiths suggested, apply ResolveUrl:

<style type="text/css">
   @import '<%= ResolveUrl("~/css/screen.css") %>';
   @import '<%= BaseURL %>/css/screen.css';
</style>

The difference between the two is seen in the rendered markup:

<style type="text/css">
    @import '/UrlRebasing/css/screen.css';
    @import 'http://localhost:1100/UrlRebasing/css/screen.css';
</style>

It’s up to you to choose relative or absolute URLs.

Wait, There’s More!

Here’s a very interesting quirk. Would rebasing take place in this declaration?

<link type="text/css" rel="stylesheet"
      href='<%= ResolveUrl("~/css/print.css") %>'/>

Yes, but the output is incorrect:

<link type="text/css" rel="stylesheet" 
href="master_pages/%3C%25=%20ResolveUrl(%22~/css/print.css%22)
%20%25%3E" />

Apparently, the parser takes the <%= %> construct too literally.

Conclusion

I’d like to emphasize that this discussion is limited to CSS and JavaScript declarations in the <head> tag of a master page. Outside of <head> no magic rebasing happens, so you’re on your own. Use ResolveUrl or BaseURL for markup inside the <body>.

Comments

Comment permalink 1 Shane Shepherd |
Why not just use Request.ApplicationPath?
Comment permalink 2 Milan Negovan |
ResolveClientUrl seems to be a good fit too. There are so many ways to skin this cat. :)
Comment permalink 3 Kent Boogaart |
You can also just plonk your css into your theme folder. Then ASP.NET will automatically add links to your head (assuming it has runat="server").

Kent
Comment permalink 4 Chris |
ASP 2.0 doesn't do url rebasing for script tags.
Comment permalink 5 greg |
I have been bashing away for 6 hours now on broken image links inside nested master pages. I have read this blog and scotts blog and Im having no luck at all. I have tried everything to get the links working:
I changed the image tags to server side tags. I moved the css file and master page file into the same directory as the web page. I tried the ResolveClientURL .... nothing works .. and yet if i view the rendered source, all the image links are correct...

HELP
Comment permalink 6 Nathanael Jones |
HtmlHead does the parsing for meta and link. It can't parse inside CPH tags.

It's easy to solve this problem at the application level, by sub-classing Page (which you should anyway).

This patch makes script, meta, and link tags work correctly regardless of how they land in the page header. It takes a quick second pass to clean up after ASP.NET.

You can also play with the acid test which demonstrates the incorrect behavior of the framework, and the correct behavior with the patch

Emails and Notifications

Would you like to be notified when somebody responds to this post?  Would you like to have these comments emailed to you?

TrackBacks

Sorry, TrackBacks are not allowed.

Submit your comment

Please enter only text since all HTML tags except hyperlinks will be stripped. Hyperlinks will become live links. Any comments with flaming or offensive language will be deleted. Be courteous to other posters. Thank you.

Your name (required):
Your email (optional):
Your site's URL (optional):
Enter this number
Type in the number above:
Comment (required):