IIS Query string lost when using URL Rewrite rules - asp.net

I am trying to get a site to work with a different URL, basically one is the real URL(fakesite.com) and the other is a Branded URL(NewFakeSite.com). So far ive managed to get it to work so that:
http://fakesite.com/uv/ExpressBranding/ExpressHome.aspx
and
http://NewFakeSite.com/uv/ExpressBranding/ExpressHome.aspx
Both go to the same site and are both able to work as functioning sites. The Problem comes with Querystrings, I cant seem to get the second site to pass along the Querystring so if I go to a URL with a Querystring like:
http://fakesite.com/uv/EnviSetup/Wizard/GeneralInformation.aspx?DashboardId=0
For the Second site it cant find the page and instead gives me:
https://NewFakeSite.com/uv/EnviSetup/Wizard/GeneralInformation.aspx
with no QueryString at all.As such I need to add the Querystring. My webconfig is below, its not just my code so certain pieces of it like the HTTP to HTTPS and adding uv were not written by me.
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<rewrite>
<rules>
<remove name="Redirect to HTTPS" />
<remove name="Redirect to add uv folder to dotcom" />
<rule name="Redirect to add uv folder to dotcom" enabled="true" stopProcessing="true">
<match url=".*" />
<conditions logicalGrouping="MatchAll" trackAllCaptures="false">
<add input="{map add uv after dotcom:{REQUEST_URI}}" pattern="(.+)" />
</conditions>
<serverVariables />
<action type="Redirect" url="{C:1}" appendQueryString="false" />
</rule>
<rule name="Redirect to HTTPS" enabled="true" stopProcessing="true">
<match url="(.*)" />
<conditions logicalGrouping="MatchAll" trackAllCaptures="false">
<add input="{HTTPS}" pattern="^OFF$" />
<add input="{SERVER_NAME}" pattern="opterra\.esightenergy\.com" negate="true" />
</conditions>
<serverVariables />
<action type="Rewrite" url="https://{HTTP_HOST}/{R:1}" appendQueryString="false" />
</rule>
<rule name="AddQueryStringForENVIDashBoards">
<match url="https://prod.utilityvision.com/uv/EnviSetup/EnviDashboardList.aspx(\?(.*))" />
<action type="Rewrite" url="HTTPS://opterra.esightenergy.com/uv/EnviSetup/Wizard/{C:1}" appendQueryString="false" />
<conditions>
<add input="{URL}" pattern="https://prod.utilityvision.com/uv/EnviSetup/Wizard/(.*)" />
</conditions>
</rule>
</rules>
</rewrite>
<httpRedirect enabled="false" destination="" exactDestination="false" childOnly="false" />
</system.webServer>
</configuration>
Any Help would be greatly appreciated I am new to IIS so I hope this is even possible. Thanks!
EDIT: I have tried setting the appendQueryString="True" but still no Querystring. Thanks mjw.
Edit 2: The main goal is to make make it so the URL shows up as something different then it was originally programmed as, The problem is the Query String doesnt come with the rest of the new URL. I have added some code changes to see if this would fix the problem but it did not the URL remained the same. The code sample above is not the original I added this:
<rule name="AddQueryStringForENVIDashBoards">
<match url="https://prod.utilityvision.com/uv/EnviSetup/EnviDashboardList.aspx(\?(.*))" />
<action type="Rewrite" url="HTTPS://opterra.esightenergy.com/uv/EnviSetup/Wizard/{C:1}" appendQueryString="false" />
<conditions>
<add input="{URL}" pattern="https://prod.utilityvision.com/uv/EnviSetup/Wizard/(.*)" />
</conditions>
</rule>

You have server variable for query string so you can use it to append value to the redirection url:
QUERY_STRING
So for your request http://fakesite.com/uv/EnviSetup/Wizard/GeneralInformation.aspx?DashboardId=0
Important Server variable values are:
HTTP_HOST: www.fakesite.com
PATH: /uv/EnviSetup/Wizard/GeneralInformation.aspx
QUERY_STRING: DashboardId=0
Also if you open IIS->Url Rewrite and go to your rule you will see there is a option to test rule, you can simply paste your url and have an overview how URL is parsed. You will then also realize which part you can use to append query string.
http://www.iis.net/learn/extensions/url-rewrite-module/testing-rewrite-rule-patterns

Related

URL rewrite for Google analytics

I have searched through many S.O. questions and answers, but haven't seen a good solution for this. I have already created and well-established SEO URLs in my web.config file. I was using a rewriteMap to basically turn my product pages into any URL that I needed.
Here is what I have to do this:
<rule name="Redirect Rule" enabled="true" stopProcessing="true">
<match url=".*" />
<conditions>
<add input="{RedirectMapName:{REQUEST_URI}}" pattern="(.+)" />
</conditions>
<action type="Redirect" url="{C:1}" appendQueryString="false" redirectType="Permanent" />
</rule>
<rule name="Rewrite Rule" stopProcessing="true">
<match url=".*" />
<conditions>
<add input="{RewriteMapName:{REQUEST_URI}}" pattern="(.+)" />
</conditions>
<action type="Rewrite" url="{C:1}" />
</rule>
What is being requested now is to add in Google Analytics parameters in order to track campaigns. If I simply add in the parameters, it will of course, give me a 404 error. I am now trying to get these SEO URLs to pick up these parameters, but getting quite frustrated.
If I remove the query string, Google Analytics will not pick it up since it is a client side script. Something like this might be close, but I am not pointing to any specific page.
URL Rewrite with Query String
This is how I remove the querystring:
<rule name="Subject redirect with query" stopProcessing="true">
<match url="^(.*)" />
<conditions trackAllCaptures="true">
<add input="{QUERY_STRING}" pattern="^utm_source=([^=&]+)&utm_medium=([^=&]+)&utm_campaign=([^=&]+)&?(.*)$" />
</conditions>
<action type="Redirect" url="{R:1}" appendQueryString="false" redirectType="Permanent" />
</rule>
Summed up, how do I turn this:
https://www.example.com/fancy-url
to this
https://www.example.com/fancy-url?utm_source=Targeted_Email&utm_medium=email&utm_campaign=campaigntag
After much frustration, I was able to figure this out. The query string was okay, but one of the settings was preventing the rest of the rules to be processed. After the rule name, I had stop processing set to true. When I looked at it in IIS, the setting is much more descriptive. It says "Stop processing of subsequent rules". Once I removed that and moved this above my other rules, worked perfectly.
<rule name="Google Query string">
<match url="(.*)$" />
<conditions>
<add input="{QUERY_STRING}" pattern="utm_source=([^=&]+)&utm_medium=([^=&]+)&utm_campaign=([^=&]+)&?(.*)$" />
</conditions>
<action type="Rewrite" url="{R:0}" appendQueryString="false" />
</rule>

IIS Re-write module not working for default document request

I'm trying to use the IIS rewrite module to redirect HTTP to HTTPS for certain areas of my site.
It works mostly. However I've noticed a strange inconsistency if the request uses the default document.
For example...
http://[mydomain]/test_folder/default.aspx
correctly redirects to...
https://[mydomain]/test_folder/default.aspx
However, this URL...
http://[mydomain]/test_folder/
does not redirect.
My re-write rules are defined as follows...
<rewrite>
<rules>
<rule name="Redirect to HTTPS" stopProcessing="true">
<match url="(.*)" />
<conditions>
<add input="{HTTPS}" pattern="^OFF$" />
<add input="{HTTP_HOST}" pattern="^mydomain.com$" ignoreCase="true" />
<add input="{SCRIPT_NAME}" pattern="^/(?:admin|test_).*" ignoreCase="true" />
</conditions>
<action type="Redirect" url="https://{HTTP_HOST}/{R:1}" redirectType="Permanent" />
</rule>
</rules>
</rewrite>
My default documents are defined as follows...
<defaultDocument enabled="true">
<files>
<clear />
<add value="default.asp" />
<add value="default.aspx" />
</files>
</defaultDocument>
It's like having processed the request for the default document, it doesn't bother to process my rewrite rules.
Can anyone suggest what I might be doing wrong, and how to resolve it?
Update: I've been able to work around the problem by removing the rewrite rules, and instead doing the redirection in global.asax. This seems like a slightly hacky way to do it though, so I would prefer to use IIS rewrite if there is a proper solution.
This rule will redirect all requests which stars with admin or test_:
<rule name="redirect to HTTPS" stopProcessing="true">
<match url="^(admin|test_)" />
<conditions>
<add input="{HTTPS}" pattern="^OFF$" />
<add input="{HTTP_HOST}" pattern="^mydomain.com$" ignoreCase="true" />
</conditions>
<action type="Redirect" url="https://{HTTP_HOST}{REQUEST_URI}"/>
</rule>
Example:
http://[mydomain]/test_folder/default.aspx to https://[mydomain]/test_folder/default.aspx
http://[mydomain]/admin/default.aspx to https://[mydomain]/admin/default.aspx
http://[mydomain]/test_folder/ to https://[mydomain]/test_folder/

IIS url rewrite, broken href (css, js etc)

I am using IIS url rewriting module in asp.net application, my problem is any internal relative references like js, css, images are now pointing to wrong url after this url rewrite, below is my rewriting rule
<rewrite>
<rules>
<rule name="pk" patternSyntax="ECMAScript">
<match url="pk/([a-z]+).aspx" />
<action type="Rewrite" url="{R:1}.aspx?mid=1" />
<conditions logicalGrouping="MatchAny">
<add input="{REQUEST_FILENAME}" pattern="(\.css|\.js)$" negate="true" />
</conditions>
</rule>
</rules>
</rewrite>
In above rewrite any url with "pk/page_name.aspx" is being translated to page_name.aspx?mid=1, this is working fine, however references to js,css and images in master page are now also pointing to "pk/files/js/jquery.js" while in my application it should be "files/js/jquery.js", Please help me solve this issue.
I am able to solve this issue by myself, Earlier i was doing it completely wrong, I was doing just a rewrite which is causing problem, I solved this by first "Redirecting" the page to the desired URL and then "Rewriting" that URL to the one which my application understand. Following are my configuration
<rewrite>
<rules>
<rule name="Redriect for Markets" stopProcessing="true">
<match url="([a-z]+)\.aspx" />
<action type="Redirect" url="/{id:{C:1}}/{R:1}.aspx" appendQueryString="false" />
<conditions>
<add input="{REQUEST_FILENAME}" pattern="(\.css|\.js|\.jpg|\.png|\.woff|\.tiff|\.gif|\.dev|\.swf)$" negate="true" />
<add input="{QUERY_STRING}" pattern="mid=(.+)" />
</conditions>
</rule>
<rule name="Rewrite for Markets" stopProcessing="true">
<match url="([a-z][a-z])/(.*)" />
<action type="Rewrite" url="{R:2}?mid={marketId:{R:1}}" />
<conditions logicalGrouping="MatchAny">
<add input="{REQUEST_FILENAME}" pattern="(\.css|\.js|\.jpg|\.png|\.woff|\.tiff|\.gif|\.dev|\.swf)$" negate="true" />
</conditions>
</rule>
</rules>
<rewriteMaps>
<rewriteMap name="id">
<add key="1" value="pk" />
</rewriteMap>
<rewriteMap name="marketId">
<add key="pk" value="1" />
</rewriteMap>
</rewriteMaps>
</rewrite>
After doing this my URL which is like https://www.mydomain.com/index.aspx?mid=1 is first "Redirected" to https://www.mydomain.com/pk/index.aspx and then "Rewritten" to https://www.mydomain.com/index.aspx?mid=1 internally. So my browser window show URL as https://www.mydomain.com/pk/index.aspx and value I get in Request.QueryString["mid"] is 1, which is exactly what i wanted.
One thing more for internal URLs to work I have to take the base URL in master page currently it is set to "/"

IIS URL Rewrite with multiple query string

Im really new in URL Rewriting and trying to rewrite / redirect multiple query but seems not working. Since this is the search result and comes with different filtering the queries may vary. For example is some search we may have the query of t1=something and in the other we may have t2=somethingelse and sometimes we may combine them like: t1=something&t2=somethingelse
Im using IIS7 with web.config and here is what I have done so far:
This is my example link
www.website.com/search/?t1=first&t2=second
I have tried the following and non of them actually worked:
(1)
<rewrite>
<rules>
<rule name="first" stopProcessing="true">
<match url="search/" />
<conditions trackAllCaptures="true">
<add input="{QUERY_STRING}" pattern="t1=([0-9a-zA-Z]+)" />
</conditions>
<action type="Redirect" url="search/{C:1}/" appendQueryString="false" />
</rule>
<rule name="second" stopProcessing="true">
<match url="search/" />
<conditions trackAllCaptures="true">
<add input="{QUERY_STRING}" pattern="t2=([0-9a-zA-Z]+)" />
</conditions>
<action type="Redirect" url="search/{C:1}/" appendQueryString="false" />
</rule>
</rules>
</rewrite>
(2)
<rule name="a" stopProcessing="true">
<match url="search2/" />
<conditions trackAllCaptures="true">
<add input="{QUERY_STRING}" pattern="t1=([0-9a-zA-Z]+)" />
<add input="{QUERY_STRING}" pattern="t2=([0-9a-zA-Z]+)" />
</conditions>
<action type="Redirect" url="search2/{C:1}/{C:2}" appendQueryString="false" />
</rule>
I would really appreciate any help.
Thanks.
Also, this post might provide the answer -
Tracking Capture Groups Across Conditions setting
EDIT: the example from the link above
Note the trackAllCaptures=true
<rule name="Back-references with trackAllCaptures set to true">
<match url="^article\.aspx" >
<conditions trackAllCaptures="true">
<add input="{QUERY_STRING}" pattern="p1=([0-9]+)" />
<add input="{QUERY_STRING}" pattern="p2=([a-z]+)" />
</conditions>
<action type="Rewrite" url="article.aspx/{C:1}/{C:2}" /> <!-- rewrite action uses back-references to both conditions -->
</rule>
I thought I'd share a link of what I had found -
possible answer here
Also, to separate multiple parameters you can use a pipe operator. For example, something like this:
parm1=(\w+)|parm2=(\w+)
apply target URL with {C:1} and {C:2}
So, URL like this:
yourapp/list.aspx?parm1=abc&parm2=123
will result in back references as follows - {C:1}=abc and {C:2}=123

IIS7 URL Rewriting: How not to drop HTTPS protocol from rewritten URL?

I'm working on a website that uses IIS 7's URL rewriting feature to do a permanent redirect from example.com to www.example.com, as well as rewrites from similar domain names to the "main" one, such as from www.examples.com to www.example.com.
This rewrite rule - shown below - has worked well for some time now. However, we recently added HTTPS support and noticed that if users visit one of the URLs to be rewritten to www.example.com then HTTPS is dropped. For instance, if a user visits https://example.com they get redirected to http://www.example.com, whereas we would like them to be sent to https://www.example.com.
Here is the rewrite rule of interest (in Web.config):
<rule name="Canonical Host Name" stopProcessing="true">
<match url="(.*)" />
<conditions logicalGrouping="MatchAny">
<add input="{HTTP_HOST}" pattern="^example\.com$" />
<add input="{HTTP_HOST}" pattern="^(www\.)?example\.net$" />
<add input="{HTTP_HOST}" pattern="^(www\.)?example\.info$" />
<add input="{HTTP_HOST}" pattern="^(www\.)?examples\.com$" />
</conditions>
<action type="Redirect" url="http://www.example.com/{R:1}" redirectType="Permanent" />
</rule>
As you can see, the action element's url attribute points directly to http://, so I get why https://example.com is redirected to http://www.example.com. My question is, how do I fix this? I tried (naively) to just drop the http:// part from the url attribute, but that didn't work.
Here's Scott's answer with Hasan's improvements. This should cover mixed SSL/non-SSL sites. The rule basically says "if the url does not have www.example.com", do a permanent redirect to it. Essentially... you are redirecting people who visit you without www or directly to your IP address.
<rewrite>
<rules>
<rule name="Canonical Host Name" stopProcessing="true">
<match url="(.*)" />
<conditions logicalGrouping="MatchAll">
<add input="{HTTP_HOST}" pattern="^www\.example\.com$" negate="true" />
</conditions>
<action type="Redirect" url="{MapSSL:{HTTPS}}www.example.com/{R:1}" redirectType="Permanent" />
</rule>
</rules>
<rewriteMaps>
<rewriteMap name="MapSSL" defaultValue="http://">
<add key="ON" value="https://" />
<add key="OFF" value="http://" />
</rewriteMap>
</rewriteMaps>
</rewrite>
Figured out the answer with some help from my colleagues.
I needed to use multiple rules with a condition on {HTTPS}. Note the {HTTPS} condition in the rules below.
<rule name="Canonical Host Name (HTTP)" stopProcessing="true">
<match url="(.*)" />
<conditions logicalGrouping="MatchAny">
<add input="{HTTPS}" pattern="OFF" />
<add input="{HTTP_HOST}" pattern="^example\.com$" />
</conditions>
<action type="Redirect" url="http://www.example.com/{R:1}" redirectType="Permanent" />
</rule>
<rule name="Canonical Host Name (HTTPS)" stopProcessing="true">
<match url="(.*)" />
<conditions logicalGrouping="MatchAny">
<add input="{HTTPS}" pattern="ON" />
<add input="{HTTP_HOST}" pattern="^example\.com$" />
</conditions>
<action type="Redirect" url="https://www.example.com/{R:1}" redirectType="Permanent" />
</rule>
I then repeated the rule pair above for the alternate domain names.
If you just want to redirect based on the currently used protocol (as per your last sample) then there's a much simpler solution that will halve the amount of rules you will need. The following is what I've learned from a collegue of mine.
As you've seen, the {HTTPS} argument will contain the value ON or OFF. You can map this value to https:// or http:// by feeding this value into a rewritemap.
Here's how this would work:
1- Create a rewritemap section for mapping the {HTTPS} value:
<rewriteMap name="MapProtocol" defaultValue="OFF">
<add key="ON" value="https://" />
<add key="OFF" value="http://" />
</rewriteMap>
It's up to you to decide if you want to only include the protocol, or the semicolon and forward slashes as well. It doesn't matter for the solution, but keep it in mind wherever you refer to it.
2- Refer to this map wherever you need. In this sample it's used in outbound-rules, but it'll also work in your scenario:
<rule name="Outbound-Rule Name" stopProcessing="true" preCondition="ResponseIsHtml">
<match filterByTags="A, Link, Script" pattern="YOUR PATTERN" />
<action type="Rewrite" value="{MapProtocol:{HTTPS}}{HTTP_HOST}/REST OF RELATIVE LINK HERE" />
</rule>
That's it, the URL Rewrite module should now automagically use the correct protocol for your links depending on if you're using https, or, of course, http.
Hope this helps!
Here's a cross-domain solution which works not only on example.com but also on any domain
<rewrite>
<rules>
<rule name="Canonical Host Name" stopProcessing="true">
<match url="(.*)" />
<conditions logicalGrouping="MatchAll">
<add input="{HTTP_HOST}" pattern="^www\.([.a-zA-Z0-9]+)$" negate="true" />
</conditions>
<action type="Redirect" url="{MapProtocol:{HTTPS}}www.{HTTP_HOST}/{R:0}" redirectType="Permanent" />
</rule>
</rules>
<rewriteMaps>
<rewriteMap name="MapProtocol" defaultValue="OFF">
<add key="ON" value="https://" />
<add key="OFF" value="http://" />
</rewriteMap>
</rewriteMaps>
</rewrite>

Resources