IIS 7 URL rewrite module web.config section c# - iis-7

We are using IIS7 URL rewrite module with asp.net C#, all of the URLs are configured and written directly into web.config:
<system.webServer>
<!-- ... -->
<rewrite>
<rules>
<clear />
<rule name="Category URL" stopProcessing="true">
<match url="somepage.aspx" ignoreCase="false"/>
<conditions logicalGrouping="MatchAll" trackAllCaptures="false">
<add input="{QUERY_STRING}" pattern="REDIRECTION=true"
ignoreCase="false"/>
<add input="{QUERY_STRING}" pattern="categoryid=([^&]*)"/>
</conditions>
<action type="Redirect" url="http://{HTTP_HOST}/browsing/categorylanding.aspx?navcategoryid={C:1}"/>
</rule>
</rules>
</rewrite>
</system.webServer>
I need to move this to a section so that I can have seperate rules for QA, DEV and Production, what would be the "type that i would define in the section?
<configSections>
<section name="IISURLRewriteSection" type="???"/>
</configSections>
Will the IIS automatically pick up these settings once moved outside from web.config to another custom config file?

We resorted to writing our own HTTPModule since from debugging point of view as well any issues that would arise at IIS level would have to have the Operations team involved - just following a process defined in our org :)

The best solution, imho, would be to move the configuration details into external files, which you can then swap out per-environment.
This is pretty easy to do using the method described in Moving IIS7 url rewrite section out of the web.config file, where you would have something like this in your Web.config file:
<system.webServer>
<rewrite configSource="rewrite.config"/>
</system.webServer>
Then you can store the environment specific stuff in a separate file, rewrite.config, looking something like this:
<rewrite>
<rules>
<clear />
<rule name="Category URL" stopProcessing="true">
<!-- ... --->
</rule>
</rules>
</rewrite>

Related

Redirect Rule in web.config not including folder path

I'm working on a client application where they have a nested HTML-only app in a rooted subfolder of an otherwise ASP.NET application.
The domain name is changing for the HTML app only, and I need to be sure that the requests are routed to the new domain name. So, using the rewriteRules sounds like a perfect tool for this, but I'm doing something wrong and need another set of eyes.
The original URL is something like this:
https://example.com/folder1/folder2/app/index.html
The new domain is on an entirely different server and I want all requests from the app folder to go to the new domain name. Here is an example:
https://newdomain.com/folder1/folder2/app/index.html
Unfortunately, I'm doing something wrong that's probably obvious... I keep getting this URL in the redirect.
https://newdomain.com/index.html
Here is the web.config showing what I tried. It's in the app folder.
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.web>
<customErrors mode="Off" />
</system.web>
<system.webServer>
<rewrite>
<rules>
<rule name="RedirectHtmlApp" stopProcessing="true">
<match url="^(.*)$" ignoreCase="true" />
<conditions logicalGrouping="MatchAny">
<add input="{HTTP_HOST}" pattern="^(www\.)?example\.com$" />
</conditions>
<action type="Redirect" url="https://newdomain.com/{R:0}" redirectType="Permanent" appendQueryString="true" />
</rule>
</rules>
</rewrite>
</system.webServer>
</configuration>
{R:0} and {R:1} both return index.html.
What is passed to {R:0} is relative. So if your web.config is in /folder1/folder2/app/{here} then "folder1/folder2/app/" are not passed along. If your web.config rule is in the root of the site-app above /folder1, then I am wrong, but if I am right, then you just need to include the path to the root of the app at the destination also. Given what you have above,
<action type="Redirect"
url="https://newdomain.com/folder1/folder2/app/{R:0}"
redirectType="Permanent" appendQueryString="true" />

Hosting Symfony 3 inside subdirectory on IIS

I have a really harsh time trying to get Symfony 3 app work on IIS as website subdirectory.
Structure on IIS :
Application is called pfc and its poiting to directory pfc/web, (IIS is hiding root, because folder name is same as app)
This is web.config:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<defaultDocument>
<files>
<add value="app_dev.php" />
</files>
</defaultDocument>
<rewrite>
<rules>
<clear />
<rule name="StaticFiles" stopProcessing="true">
<match url="^(.*)$" />
<conditions logicalGrouping="MatchAll" trackAllCaptures="false">
<add input="{REQUEST_FILENAME}" matchType="IsFile"/>
</conditions>
<action type="Rewrite" url="{R:0}" logRewrittenUrl="true" />
</rule>
<rule name="Symfony 3" enabled="true" stopProcessing="true">
<match url=".?" ignoreCase="false" />
<conditions logicalGrouping="MatchAll" trackAllCaptures="false" />
<action type="Rewrite" url="./app_dev.php" />
</rule>
</rules>
</rewrite>
</system.webServer>
</configuration>
Entering dev.erp.loc/Test2/pfc ends up with:
like Symfony thinks of itself as a root application, which is not.
My best shoot was to use router.request_context.base_url, but it looks like it worked only in S2.
Now im stuck on something i can call half-way solution
By comment rewrite section in web.config i was correctly redirected to Identity Server, but after log in i get :
In order to fix it, i needed to uncomment rewrite section, to make routing work again, but it works only for browser, leaving it in this state will cause "no route found" in anther browser.
It would be nice to fix subdirectory routing in parameters.yml, which I fill anyway in deploy script, but if there is no other way I can edit web.config too.
Recently I needed to take care of similar issue and as side effect I solved this "problem". My URL without trailing slash is correct. The issue was that Chrome couldn't create canonical url form and made request to endpoint that Symfony don't need to interpret

Replacing IIS rewrite rules in web.config transform

I have some IIS rewrite rules that I want to vary by environment. The development rewrite rules are in the web.config file, then at the end of the web.test.config file I have:
<appSettings>
...Some app settings tranforms here
</appSettings>
<system.webserver>
<rewrite xdt:Transform="Replace">
<rules>
... rules here
</rules>
</rewrite>
</system.webserver>
</configuration>
My app settings are getting transformed when I deploy to test, but by IIS rewrite rules are not. I was hoping the entire <rewrite> section would simply be replaced with the one in the transform file (as per http://msdn.microsoft.com/en-us/library/dd465326.aspx), but nothing is changing.
I have tried putting xdt:Transform="Replace" xdt:Locator="Match(name)"> on the individual rules too:
<rule name="Test rule" stopProcessing="true" xdt:Transform="Replace" xdt:Locator="Match(name)">
But again this makes no difference.
Is it even possible to replace rewrite rules in the web.config and if so, what am I missing?
As I didn't have any rewrite rules in my main web.config, the Replace transform didn't work. I successfully used the Insert transform, as below:
<system.webServer>
<rewrite xdt:Transform="Insert">
<rules>
<rule name="CanonicalHostNameRule1">
<match url="(.*)" />
<conditions>
<add input="{HTTP_HOST}" pattern="^www\.mysite\.com$" negate="true" />
</conditions>
<action type="Redirect" url="http://www.mysite.com/{R:1}" />
</rule>
</rules>
</rewrite>
</system.webServer>
There is a lot of answers here with examples which is a good thing, but I think few details are missing. I have wrote about this in my website, the key point here is to add xdt:Transform="Insert" in the root tag hierarchy you want to be added for the respective environment.
By default you have your Web.config file, but you have also Web.Debug.config and Web.Release.config as seen in the image below:
Lets say you want to added a redirection from http to https in your release of the application. Then edit Web.Release.config and add following lines:
<?xml version="1.0"?>
.....
<system.webServer>
<rewrite xdt:Transform="Insert">
<rules>
......
</rules>
</rewrite>
</system.webServer>
</configuration>
So next time you publish your project the tag with rewrite and its sub-content will be added to web.config file.
To see that before you publish, right click on Web.Release.config and click Preview Transform.
You will see the difference between initial version and release version.
Reference:
HTTP to HTTPS Redirect - IIS 8.5 not working properly
Microsoft Web.Config file transformations
Disclaimer: the link of this guideline refer to my personal web site.
The rewrite section worked weirdly to me at first when creating the release configs, errors and sections not showing at all. This is how i solved it.
Microsoft (R) Build Engine version 12.0.31101.0
Microsoft .NET Framework, version 4.0.30319.0
Edit After messing about with this i realized that having the rewrite tag on a server that does not have the rewrite plugin make the webserver return an error. I want different configurations on server and local development machine so the fix is:
The un-transformed web.config only needs a <system.webServer> tag and in the web.config.release for a basic canonical host name rule
<configuration>
<system.webServer>
<rewrite xdt:Transform="Insert">
<rules>
<rule name="CanonicalHostNameRule" xdt:Transform="Insert">
<match url="(.*)" />
<conditions>
<add input="{HTTP_HOST}" pattern="^www\.host\.com$" negate="true" />
</conditions>
<action type="Redirect" url="http://www.host.com/{R:1}" />
</rule>
</rules>
</rewrite>
</system.webServer>
</configuration>
The action didn't need a name at all but the rewrite tag needs the xdt:Transform="Insert"
Obviously if you want it on your local machine as well, it would need an update instead.
It is possible to transform the rewrite section of system.webServer. I was initially having the same problem and realized that I had inadvertently placed the rewrite node incorrectly under system.web. While this does not look like your problem based on the limited snippet that you provided, I would still suspect that your issue is related to node placement in the transform file.
Here is what my Web.Debug.config looks like (and this version is writing the correct Web.config on a debug build):
<?xml version="1.0"?>
<!-- For more information on using web.config transformation visit http://go.microsoft.com/fwlink/?LinkId=125889 -->
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
<!--
In the example below, the "SetAttributes" transform will change the value of
"connectionString" to use "ReleaseSQLServer" only when the "Match" locator
finds an atrribute "name" that has a value of "MyDB".
<connectionStrings>
<add name="MyDB"
connectionString="Data Source=ReleaseSQLServer;Initial Catalog=MyReleaseDB;Integrated Security=True"
xdt:Transform="SetAttributes" xdt:Locator="Match(name)"/>
</connectionStrings>
-->
<system.web>
<!--
In the example below, the "Replace" transform will replace the entire
<customErrors> section of your web.config file.
Note that because there is only one customErrors section under the
<system.web> node, there is no need to use the "xdt:Locator" attribute.
<customErrors defaultRedirect="GenericError.htm"
mode="RemoteOnly" xdt:Transform="Replace">
<error statusCode="500" redirect="InternalError.htm"/>
</customErrors>
-->
</system.web>
<system.webServer>
<rewrite xdt:Transform="Replace">
<rules>
<clear/>
<rule name="Canonical Hostname">
<!-- Note that I have stripped out the actual content of my rules for the purposes of posting here... -->
</rule>
</rules>
</rewrite>
</system.webServer>
</configuration>
A trick I use is give the action a name
then in my transform just add xdt:Transform="SetAttributes" xdt:Locator="Match(name)" like the following
<system.webServer>
<rewrite>
<rules>
<rule name="RedirecttoWWW" enabled="true" >
<match url="(.*)" />
<conditions>
<add input="{HTTP_HOST}" negate="true" pattern="^www\.([.a-zA-Z0-9]+)$" />
</conditions>
<action name="AddWWW" type="Redirect" url="http://www.{HTTP_HOST}/{R:0}" appendQueryString="true" redirectType="Permanent" xdt:Transform="SetAttributes" xdt:Locator="Match(name)" />
</rule>
</rules>
</rewrite>
The above example is to add www to all requests
-------UPDATE-----
just an update adding name to the action will not work as wanted so I updated the code as the following
<system.webServer>
<rule name="RedirecttoWWW" enabled="true" xdt:Transform="RemoveAll" xdt:Locator="Match(name)" >
</rule>
<rule name="RedirecttoWWW" enabled="true" xdt:Transform="InsertIfMissing" xdt:Locator="Match(name)" >
<match url="(.*)" />
<conditions>
<add input="{HTTP_HOST}" negate="true" pattern="^www\.([.a-zA-Z0-9]+)$" />
</conditions>
<action type="Redirect" url="http://{HTTP_HOST}/{R:0}" appendQueryString="true" redirectType="Permanent" />
</rule>
</rules>
</rewrite>
</system.webServer>

a web application in the cloud as a subfolder of the main company URL

Is it possible to deploy a web application in the cloud and configure it so that it appears like a subfolder in the company URL.
E.g.
www.mycompany.com //main company web site
www.mycompany.com/products // hits a web application in the cloud (azure for example)
thanks
Having in mind it is easier to do with sub-domain and CNAME, I think that what you are looking for is the IIS URL Rewrite module.
The following base rules are taken from this IIS Forum's thread, as a similar situation is described and samples rules are given. You may use them as a base:
<system.webServer>
<rewrite>
<rules>
<rule name="CanonicalHostNameRule">
<match url="(.+)/(.*)" />
<conditions>
<add input="{HostToRedirect:{HTTP_HOST}/{R:1}}" pattern="(.+)" />
</conditions>
<action type="Redirect" url="http://{C:1}/{R:2}" />
</rule>
</rules>
<rewriteMaps>
<rewriteMap name="HostToRedirect">
<add key="domain.com/mail" value="mail.domain.com" />
<add key="domain.net/mail" value="mail.domain.net" />
</rewriteMap>
</rewriteMaps>
</rewrite>
</system.webServer>
You may also check this SO question, as it is providing some guides on the problem you are trying to solve.
UPDATE WITH SOLUTION
This is totally achievable with URL Rewrite module for IIS in combination with ARR module. Then you need to set a Reverse Proxy rule that will rewrite all /products requests to the corresponding web app in the cloud. Your rule will look something like that:
<system.webServer>
<rewrite>
<rules>
<rule name="ReverseProxyInboundRule1" patternSyntax="ECMAScript" stopProcessing="true">
<match url="(^products)" />
<conditions>
<add input="{CACHE_URL}" pattern="^(https?)://" />
</conditions>
<action type="Rewrite" url="{C:1}://myvompany.cloudapp.net/" />
</rule>
</rules>
</rewrite>
</system.webServer>
You can tweak this later to fit your exact need, but with the above sample I just achieved what you are looking for.
I'm not a DNS expert, but I think you would find it more straightforward to route products.mycompany.com to your Windows Azure web site than a subfolder.
IIS support redirects
I also like the answer from David on making it a web site and use cname to map products.mycompany.com
You could do both. Redirect www.mycompany.com/products to products.mycompany.com

Simple IIS7 Url Rewrite doesnt work

at first. I have searched and read here a lot and googling with bing but didnt find
the solution. In my local enviroment it just works. Iam no IIS Admin so ....
i try the following
My domain "http://mysite.com/" goes to my url provided by my hosting service
(discountasp.net)
I want that this url goes to the root/mysite/ virtual directory but i want that the
url stays on "http://mysite.com/". So i defined the following rule, but it doesnt
work for me.
here is my web.config that is placed in the root directory (generated by the IIS7
Remote Administration UI)
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<rewrite>
<rewriteMaps>
<rewriteMap name="mysite">
</rewriteMap>
</rewriteMaps>
<rules>
<rule name="mysite.com" stopProcessing="true">
<match url=".*" />
<conditions>
<add input="{HTTP_HOST}" pattern="^(www.)?mysite.com" />
</conditions>
<action type="Rewrite" url="\mysite\{R:0}" />
</rule>
</rules>
</rewrite>
</system.webServer>
</configuration>
The "#Html.ActionLink" creates a link with the virtual directory
"http://mysite.com/mysite/"
I got it. Pointing my Domain directly on the subfolder and defining a Outbound rewrite rule on iis solves my problem.

Resources