Thursday, January 17, 2013

Master Pages and Relative Paths in ASP.NET


One quirk that can catch unsuspecting developers is the way that master pages handle relative paths. If all you’re using is static text, this issue won’t affect you. However, if you add <img> tags or any other HTML tag that points to another resource, problems can occur. The problem shows up if you place the master page in a different directory from the content page that uses it. This is a recommended best practice for large websites. In fact, Microsoft encourages you to use a dedicated folder for storing all your master pages. However, if you’re not suitably careful, this can cause problems when you use relative paths. For example, imagine you put a master page in a subfolder named MasterPages and add the following <img> tag to the master page:

<img src="banner.jpg" />

Assuming the file \MasterPages\banner.jpg exists, this appears to work fine. The image will even appear in the Visual Studio design environment. However, if you create a content page in another subfolder, the image path is interpreted relative to that folder. If the file doesn’t exist there, you’ll get a broken link instead of your graphic. Even worse, you could conceivably get the wrong graphic if another image has the same file name. This problem occurs because the <img> tag is ordinary HTML. As a result, ASP.NET won’t touch it. Unfortunately, when ASP.NET processes your content page, the relative path in this tag is no longer appropriate. The same problem occurs with <a> tags that provide relative links to other pages and with the <link> element that you can use to connect the master page to a style sheet.

To solve your problem, you could try to think ahead and write your URL relative to the content page where you want to use it. But this creates confusion and limits where your master page can be used. A better fix is to turn your <img> tag into a server-side control, in which case ASP.NET will fix the mistake:

<img src="banner.jpg" runat="server"/>

This works because ASP.NET uses this information to create an HtmlImage server control. This object is created after the Page object for the master page is instantiated. At this point, ASP.NET interprets all the paths relative to the location of the master page.

And as with all server-side controls, you can further clear things up by using the ~/ characters to create a root-relative path. Here’s an example that clearly points to a picture in an Images folder in the root web application folder:

<img src="~/Images/banner.jpg" runat="server"/>

Remember, the ~/ syntax is understood only by ASP.NET controls, so you can’t use this trick with an <img> tag that doesn’t include the runat="server" attribute. 

No comments:
Write comments
Recommended Posts × +