UrlRewrite – Virtual Directories and the Tilde

Last week I was making some SEO changes to one of the projects I’m working on when I ran into a problem using the tilde specifier in my runat=”server” URLs. For example,

<asp:HyperLink
     ID="m_hlContedit"
     runat="server"
     NavigateUrl="~/tools/ContentEdit/Menu.aspx"
     >Site Admin Home</asp:HyperLink>

Instead of the ~ resolving to the application directory, it was resolving to the directory the browser thought I was in. This was cause by the fact that I was doing a UrlRedirect from a subdirectory to an ASPX file in the root of my application while handling a 404 error. But the ASPX file was in the root directory. So .NET thought I was in the root directory of my application while the browser thought I was in some sub directory.

For an example of how to create virtual directories and UrlRewrites, see my previous article,

http://blog.dmbcllc.com/2008/07/17/virtual-files-using-httpcontextrewritepath/

Since I searched all over the Internet looking for a built in way to solve this problem, I came to the conclusion that, at least as far as ASP.NET 2.0 is concerned, there is no easy fix. Which leaves me with no other way of fixing the problem than with brute force.

Since I already had code that gave me the application directory, all I really needed to do was iterate over all the controls, look for the ones that had URLs (HyperLink, Image, and ImageButton, in my case) and replace the tilde with the application directory.

The first thing we need to consider is how we obtain the application directory. I do it with this code:

applicationDirectory = Request.ApplicationPath;
if (!applicationDirectory.StartsWith("/"))
    applicationDirectory = "/" + applicationDirectory;
if (!applicationDirectory.EndsWith("/"))
    applicationDirectory = applicationDirectory + "/";

I then call a method that gets called recursively

fixupHrefs(this.Controls);

You might be tempted to put this block of code in Page_Load() which may work for you. However, to have code that will work in every scenario, that is, code that has the URL’s initialized statically, code that is initialized with databinding, and code that is initialized with codebehind, you’ll want to call this in your OnPreRender overload.


protected override void OnPreRender(EventArgs e)
{
    applicationDirectory = Request.ApplicationPath;
    if (!applicationDirectory.StartsWith("/"))
        applicationDirectory = "/" + applicationDirectory;
    if (!applicationDirectory.EndsWith("/"))
        applicationDirectory = applicationDirectory + "/";
    fixupHrefs(this.Controls);
    base.OnPreRender(e);
}

(note, applicationDirectory is a member variable because we are going to use it in fixupHrefs()).

So all that is left is to do the fix up.

private void fixupHrefs(ControlCollection cc)
{
    foreach (Control c in cc)
    {
        if (c is HyperLink)
        {
            HyperLink h = (HyperLink)c;
            if(h.ImageUrl.StartsWith("~"))
            {
                h.ImageUrl = h.ImageUrl.Replace("~/", applicationDirectory);
            }
            if(h.NavigateUrl.StartsWith("~"))
            {
                h.NavigateUrl = h.NavigateUrl.Replace("~/", applicationDirectory);
            }
        }
        else if (c is Image)
        {
            Image i = (Image)c;
            if (i.ImageUrl.StartsWith("~"))
                i.ImageUrl = i.ImageUrl.Replace("~/", applicationDirectory);
        }
        else if (c is ImageButton)
        {
            ImageButton i = (ImageButton)c;
            if (i.ImageUrl.StartsWith("~"))
                i.ImageUrl = i.ImageUrl.Replace("~/", applicationDirectory);
        }
        else
            fixupHrefs(c.Controls);
    }
}

This code loops through all of the controls on the form, determines if it is a type that needs to be fixed, and then replaces “~/” with the application directory.

Hope this helps somebody who is having a similar problem.


Other Related Items:

High Polish Chrome Engraved Zippo Lighter - TildeHigh Polish Chrome Engraved Zippo Lighter - TildeGenuine Zippo windproof lighter packaged in a black plastic gift box with the famous Zippo lifetime guarantee.
Don't Mess With Me... Programmer on Long Sleeve Women's Cotton T-Shirt (in 9 colors)Don't Mess With Me... Programmer on Long Sleeve Women's Cotton T-Shirt (in 9 colors)100% preshrunk heavyweight cotton; double-needle stitching throughout; seamless rib at neck; shoulder-to-shoulder tape; heather grey is 90% cotton, 10% polyester; fashion cut; 5/8" rib collar; fitted tapered sleeve.

Related Post

3 Responses to “UrlRewrite – Virtual Directories and the Tilde”

DotNetNuke Sponsor

 

Most Valuable Blogger
Sponsor