A catalogue of my discoveries in software development and related subjects, that I think might be of use or interest to everyone else, or to me when I forget what I did!
ASP.NET URL Rewriting and Tilde
Tuesday, 4 November 2008
In ASP.NET controls you can use the tilde '~' character to signify the virtual application root of the website, for example when sourcing an image for an ImageButton.
Code:
This is fine for most cases. However, when using URL rewriting (via HttpHandlers) it can become a problem, since ASP.NET will calculate the path to the resource based on the location of the physical page it is rendering (not the page requesed in the browser [RawUrl]). If the resource is in a directory below the page directory, then it will render a relative path to the HTML, (and not an absolute path from the app root).
When your browser sees a relative path in the HTML it appends that to the current working directory to retreive the resource, which for a page being served up via a rewrite, is probably the wrong directory.
For example, imagine you have the following directory structure:
/MyButtonPage.aspx
/images/button.png
/subdir/page-served-by-httphandler-mapping-to-mybuttonpage.aspx
If you view '/MyButtonPage.aspx' (containing the code from above) the output path to the image would be 'images/button.png'. Your browser will therefore retreive '/images/button.png' which is correct.
However, if you view '/subdir/page-served-by-httphandler-mapping-to-mybuttonpage.aspx' (which rewrites internally the '/MyButtonPage.aspx') then ASP.NET will again render the image path as 'images/button.png' (since it is relative to the 'MyButtonPage.aspx' which was rendered internally). Your browser will now try to retrieve, '/subdir/images/button.png' which does not exist.
A workaround for this problem is to not use the tilde mechanism and instead reference the absolute path to the resource in the code.
e.g.
However, this will reference from the website root, not the application root, so be careful if your site runs as a virtual application within another site.
Code:
<asp:ImageButton ID="ImageButton1" runat="server" AlternateText="Example Button" ImageUrl="~/images/button.png" />
This is fine for most cases. However, when using URL rewriting (via HttpHandlers) it can become a problem, since ASP.NET will calculate the path to the resource based on the location of the physical page it is rendering (not the page requesed in the browser [RawUrl]). If the resource is in a directory below the page directory, then it will render a relative path to the HTML, (and not an absolute path from the app root).
When your browser sees a relative path in the HTML it appends that to the current working directory to retreive the resource, which for a page being served up via a rewrite, is probably the wrong directory.
For example, imagine you have the following directory structure:
/MyButtonPage.aspx
/images/button.png
/subdir/page-served-by-httphandler-mapping-to-mybuttonpage.aspx
If you view '/MyButtonPage.aspx' (containing the code from above) the output path to the image would be 'images/button.png'. Your browser will therefore retreive '/images/button.png' which is correct.
However, if you view '/subdir/page-served-by-httphandler-mapping-to-mybuttonpage.aspx' (which rewrites internally the '/MyButtonPage.aspx') then ASP.NET will again render the image path as 'images/button.png' (since it is relative to the 'MyButtonPage.aspx' which was rendered internally). Your browser will now try to retrieve, '/subdir/images/button.png' which does not exist.
A workaround for this problem is to not use the tilde mechanism and instead reference the absolute path to the resource in the code.
e.g.
<asp:ImageButton ID="ImageButton1" runat="server" AlternateText="Example Button" ImageUrl="/images/button.png" />
However, this will reference from the website root, not the application root, so be careful if your site runs as a virtual application within another site.
Labels: .NET, ASP.NET, URL Rewriting