Server.MapPath() with IIS URL Rewrite Module 2.0

576 views Asked by At

I have a website in IIS, with a legacy classic asp application configured as a sub app.

I'm basically trying to create URL rewrite rules so that I don't have to change all of the relative URL's in the code.

e.g. URLS's such as "/themes/somedirectory" should be mapped to "/legacy/themes/somedirectory"

Using the URL Rewrite Module 2.0 I have a URL rewrite rule configured as follows:

<rule name="Reroute themes">
    <match url="^themes.*" />
    <action type="Rewrite" url="/legacy/{R:0}" />
</rule>

This works fine when navigating to the URL. However when using Server.MapPath(), it is not applying the rewrite rule.

Is Server.MapPath() actually supposed to take this into account? If not, how should I go about re-routing the application without modifying the code?

2

There are 2 answers

1
Chris On BEST ANSWER

I just had this problem, and for now am going with create a special MapPath variant that corresponds to my rewrite rule.

So either something like this:

string MapTheme(string themeName)
{
    return Path.Combine(Server.MapPath("/legacy"), themeName)
}

Or, if you prefer:

string MapThemePath(string themeUrl)
{
    Match m = Regex.Match("^themes/(.*)");
    if (!m.Success)
        throw new ArgumentException();
    string themeName = m.Groups[1].Value;
    return Path.Combine(Server.MapPath("/legacy"), themeName)
}

Or generalize:

string MyMapPath(string url)
{
    Match m = Regex.Match("^themes/(.*)");
    if (m.Success)
    {
        string themeName = m.Groups[1].Value;
        return Path.Combine(Server.MapPath("/legacy"), themeName)
    }
    else if (itsAnotherSpecialRewriteCase)
    {
        return doSomeSimilarTransformation();
    }
    // ...
    else
    {
        // Handle non-rewritten URLs
        return Server.MapPath(url);
    }
}

I don't especially like this, because it violates "do not repeat yourself".

1
saarp On

I was looking for the same thing so I gave it a try in a test app. It appears that Server.MapPath() does not acknowledge URL Rewrite Module rules.

Here is how I tested using an empty web project (Razor syntax):

Rewrite rule:

<system.webServer>
    <rewrite>
        <rules>
            <rule name="Rewrite rule1 for test1">
                <match url="^test1(.*)" />
                <action type="Rewrite" url="{R:1}" appendQueryString="true" />
            </rule>
        </rules>
    </rewrite>
</system.webServer>

cshtml:

<p>
    The URL for this page is @Request.Url.AbsoluteUri .
    <br />
    MapPath of /test1 is @Server.MapPath("~/test1")
    <br />
    MapPath of / is @Server.MapPath("~/")
</p>

I hit http://localhost/, then http://localhost/test1. The results were:

The URL for this page is http://localhost/ .
MapPath of /test1 is c:\src\temp\test1
MapPath of / is c:\src\temp\

So looks like mappath is basically taking System.AppDomain.CurrentDomain.BaseDirectory (or something similar) and combining it with the relative URL. On a side note, I have separately confirmed that MapPath() takes into account 1 level of virtual directory, but not a 2nd (ie. virt pointing to another location that also has a virt defined).