Root Path Reference Syntax
One of the most useful (and perhaps least-well-advertised) path-related features of ASP.NET is root path reference syntax (~). This syntax, supported in all path references in server-side control declarations, lets you add references to pages, controls, images, or other resources without hard-coding relative paths in your referring URLs. For example, suppose you wanted to reference an image file called happy.gif, located in an images subdirectory at the top of the virtual root of your application. If the page to which you wanted to add this reference was in another subdirectory of its own, you might end up with an image reference tag that looked like the following:
<img src="../images/happy.gif" />
Although using relative paths such as this will work, and it is in fact a common technique in traditional ASP pages, it is laborious and error-prone to update if the referring page ever changes location. Instead, ASP.NET supports root-relative path references using the tilde (~) character. So we could rewrite the image reference as follows:
<img runat="server" src="~/images/happy.gif" />
This new path reference to the happy.gif file would work from any file in the application, regardless of its relative location to the root directory. Note that this is possible only with server-side controls because ASP.NET must evaluate the path on the server and translate it to a relative path reference.
The following .aspx page shows several common uses for this syntax, including a user control source file reference, an anchor link, and an image file reference.
<%@ Page Language="C#" %> <%@ Register TagPrefix="uc" TagName="menu" Src="~/ctrls/menu.ascx" %> <html> <body> <form runat="server"> <uc:menu runat="server" /> <asp:HyperLink NavigateUrl="~/otherpages/hi.aspx" runat="server"> <asp:Image runat="server" ImageUrl="~/images/hi.gif"/> </asp:HyperLink> </form> </body> </html>
There may be occasions when you want to resolve a relative reference programmatically instead of declaratively. Unfortunately, there is no publicly accessible way to perform exactly the same resolution that the ~ character does for declarative path references. The closest you can come is to use the ResolveUrl method of the Control class, which will translate a ~ character in the string you pass it to a top-level reference to the name of the application. Although this should work correctly too in most cases, it is just curious that ASP.NET chose two different methods for resolving root-relative path references. The differences in the resolution between the two techniques are shown in Table 2.
Table 2 Differences Between Declarative versus Programmatic Path Resolution
|
Evaluation |
<asp:Image runat="server" ImageUrl="~/images/hi.gif" /> |
../images/hi.gif |
ResolveUrl("~/images/hi.gif") |
informit/images/hi.gif |
The following .aspx page shows a practical example of using the ResolveUrl method:
<%@ Page Language="c#" %> <script runat="server"> protected override OnLoad(EventArgs e) { _homeLink.NavigateUrl = ResolveUrl("~/default.aspx"); } </script> <html> <form runat="server"> <asp:HyperLink Runat="server" ID="_homeLink">home</asp:HyperLink> </form> </html>
The root path reference syntax can also be used in conjunction with the MapPath function described earlier. For example, suppose you had an XML file called foo.xml located in a subdirectory called data at the top of the application directory for your ASP.NET application. You could load that file into an XmlDocument from anywhere in the application using the following:
string foo = Request.MapPath("~/data/foo.xml"); XmlDocument dom = new XmlDocument(); dom.Load(foo); // use dom