Blogger :
ASP.NET Blogs
All posts :
All posts by ASP.NET Blogs
Category :
ASP.NET
Blogged date : 2008 Mar 04
Linking to a resource from a reusable control in different levels in your web app folder tree can be a tedious and not so obvious task.
We have a number of tools in our bag that we can use:
- absolute paths - http://www.yoururl.com/a/b/c/page.ext - not acceptable for reusable components
- relative paths
- current level based - a/b/c/page.ext - doesn't work for reusable components
- root based - /a/b/c/page.ext - that works good in some cases but not in every
- app based - ~/a/b/c/page.ext - perfect when you can use it
What's wrong with root based paths?
When you work on a project you often use built-in WebServer of the Visual Studio and your app runs on http://localhost:XXXX/. Everything seems to be working fine with the root based paths. Now it's time to deploy your app on a test machine. You deploy it on http://test/myBestApp/. Now all your root based paths are pointing to http://test/Page.ext instead of http://test/myBestApp/Page.ext. That's a good reason not to use root based paths.
~ (tilde)
That's a good solution that comes out of the box and takes care finding the root of your app. Ok, but what if need to build the URL on the fly like in this example:
~/Item.ext?id=<% Request.QueryString[ "id" ] %>
This won't work if you put it in a Hyperlink like this:
<asp:HyperLink ID = "hlnkItemDetails" runat = "server" NavigateUrl = '~/Item.ext?id=<% Request.QueryString[ "id" ] %>' />
Don't think about changing the quotation marks. It won't work however you try.
The universal solution - Page.ResolveUrl
Now that's what can help you in every situation (or at least all cases I can think of). Think about this case: you have a custom control in ~/items/controls/ItemViewControl.ascx. This control is used in ~/Default.aspx and ~/items/Default.aspx. You need to link to ~/items/Item.aspx?id=<query string param> from ItemViewControl.ascx. You can't use ~ (tilde), root based, current folder relative or absolute path for some of the reasons written above. This is where Page.ResoulveUrl comes into help. You can build your link in this way:
<a href='<% String.Format( "{0}?id={1}", Page.ResolveUrl( "~/items/Item.aspx" ), Request.QueryString[ "id" ] ) %>' />
Yes, it is a bit complicated, but at least you won't be worried about broken links and they will work as expected wherever you put them.