I am trying to configure a directory structure in an IIS website with rewrite rules applying at various levels. For example, consider the following structure:
Default Web Site
ââ web.config
ââ v1
ââ web.config
ââ wwwroot
ââ hello.txt
I want to be able to access hello.txt
through http://localhost/hello.txt. I have configured the web.config
at the website root level like this:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.webServer>
<rewrite>
<rules>
<rule name="Rewrite to v1" stopProcessing="false">
<match url="^(?!v1).*" />
<action type="Rewrite" url="v1\{R:0}" />
</rule>
</rules>
</rewrite>
</system.webServer>
</configuration>
And I have configured the web.config
in the v1
directory like this:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.webServer>
<rewrite>
<rules>
<rule name="Rewrite to wwwroot" stopProcessing="false">
<match url="^(?!wwwroot).*" />
<action type="Rewrite" url="wwwroot\{R:0}" />
</rule>
</rules>
</rewrite>
</system.webServer>
</configuration>
The one-level rewrite works when I access http://localhost/v1/hello.txt, but the two-level rewrite doesn't work for http://localhost/hello.txt. The IIS error page shows that the request is still resolving to the physical path â¦\v1\hello.txt
rather than â¦\v1\wwwroot\hello.txt
; see https://i.stack.imgur.com/KjdH5.png. Note that changing the rewrites to redirects allows the file to be served successfully.
Is there a way of getting this to work, or it is some limitation of the URL Rewrite Module? Microsoft seems to claim that this is supported in the URL Rewrite Module Configuration Reference:
Rules Inheritance
If rules are defined on multiple configuration levels, the URL Rewrite Module evaluates the rules in the following order:
- Evaluate all the global rules.
- Evaluate a rule set that includes distributed rules from parent configuration levels as well as rules from the current configuration level. The evaluation is performed in a parent-to-child order, which means that parent rules are evaluated first and the rules defined on a last child level are evaluated last.
I'm aware that I can make the web.config
at the website root level reference the inner wwwroot
directory directly (through url="v1\wwwroot\{R:0}"
). However, I don't want to do this. I will eventually be extending the outer web.config
to support other versions (v2
, v3
, â¦), which may or may not also have a wwwroot
subdirectory, so it would be much cleaner to maintain any version-specific rewrites to inner subdirectories in the version-specific web.config
.
I've tried using Failed Request Tracing. The outer rule, Rewrite to v1
, is logged to run successfully. There is no mention of the inner rule, Rewrite to wwwroot
.