IIS url rewrite, broken href (css, js etc) - asp.net

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 "/"

Related

IIS Query string lost when using URL Rewrite rules

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

URL rewriting in ASP.NET turning http://example.com/abcd into http://example.com/page.aspx?id=abcd

I have a problem in my web forms ASP.NET app where I would like to rewrite a url from
http://example.com/abcd
into
http://example.com/page.aspx?id=abcd
the abcd part will be unique and I cant create a folder for it
I want the users to always see the http://example.com/abcd url
would the solution be the same in Windows Azure?
Can somebody please help me with some hints?
Thank You!
In your web.config, in the system.webServer section put something like this:
<!-- This has been added to support url rewriting for ... -->
<rewrite>
<rules>
<rule name="RedirectUserFriendlyURL1" stopProcessing="true">
<match url="^Page\.aspx$" />
<conditions>
<add input="{REQUEST_METHOD}" pattern="^POST$" negate="true" />
<add input="{QUERY_STRING}" pattern="^id=([a-zA-Z]+)$" />
</conditions>
<action type="Redirect" url="{C:1}" appendQueryString="false" />
</rule>
<rule name="RewriteUserFriendlyURL1" stopProcessing="true">
<match url="^([a-zA-Z]+)$" />
<conditions>
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
<add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
</conditions>
<action type="Rewrite" url="Page.aspx?id={R:1}" />
</rule>
</rules>
</rewrite>
Please note that I have copied from the config we have in a production site and modified a little bit... needs testing.
The config should work when you have only words ([a-zA-Z]+), change the pattern to make it work for numbers.
hope it helps

url rewriting in iis7

I am running IIS7.5 and the URL Rewrite module.
I followed these step by step instructions to enable user friendly URL's:
Rule Templates for the URL Rewrite Module - User Friendly URL - rule template
If I enter the URL http://domain.com/default/ instead of http://domain.com/default.aspx the website throws 404: file not found error.
Here are my rewrite rules:
<rewrite>
<rules>
<rule name="RedirectUserFriendlyURL1" stopProcessing="true">
<match url="^demourl\.dev\.asenetechdev1\.com/default\.aspx$" />
<conditions>
<add input="{REQUEST_METHOD}" pattern="^POST$" negate="true" />
</conditions>
<action type="Redirect" url="demourl.dev.asenetechdev1.com/default"
appendQueryString="false" />
</rule>
<rule name="RewriteUserFriendlyURL1" stopProcessing="true">
<match url="^demourl\.dev\.asenetechdev1\.com/default$" />
<conditions>
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="false" />
<add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="false" />
</conditions>
<action type="Rewrite" url="demourl.dev.asenetechdev1.com/default.aspx" />
</rule>
</rules>
<outboundRules>
<rule name="OutboundRewriteUserFriendlyURL1" preCondition="ResponseIsHtml1">
<match filterByTags="A, Form, Img"
pattern="^(.*)demourl\.dev\.asenetechdev1\.com/default\.aspx$" />
<action type="Rewrite" value="{R:1}/ demourl.dev.asenetechdev1.com/default" />
</rule>
<preConditions>
<preCondition name="ResponseIsHtml1">
<add input="{RESPONSE_CONTENT_TYPE}" pattern="^text/html" />
</preCondition>
</preConditions>
</outboundRules>
</rewrite>
I also tried using Intelligencia.UrlRewriter with this. But I am able to generate friendly urls on local as well as on server, but I want extensionless url, which is working ok on my local server, but not on the live server.
Your pattern is currently not matching /default/. It is only matching /default
Changing
<match url="^demourl\.dev\.asenetechdev1\.com/default$" />
to
<match url="^demourl\.dev\.asenetechdev1\.com/default/{0,1}$" />
should do it.

IIS 7 Wordpress URL Redirect

So I have a site.com/blog/12/12/articleNames and i want to redirect everything to site.com/articles/12/12/articleNames instead.
so in my blog folder i have this in my web.config
<rewrite>
<rules>
<rule name="articleMove" stopProcessing="true">
<match url="^blog/([0-9]+)/([0-9]+)/([_0-9a-z-])/" />
<conditions>
<add input="{REQUEST_FILENAME}" matchType="IsFile" />
<add input="{REQUEST_FILENAME}" matchType="IsDirectory" />
</conditions>
<action type="Rewrite" url="/articles/{R:1}/{R:2}/{R:3}" />
</rule>
</rules>
</rewrite>
However, i still keep getting the 404 page.
Use IIS Failed Request Tracing to further investigate what is happening "behind the scenes".
<rule name="articleMove" stopProcessing="true">
<match url="^([0-9]+)/([0-9]+)/([_0-9a-z-]+)" />
<action type="Redirect" url="/articles/{R:1}/{R:2}/{R:3}" />
<conditions>
</conditions>
</rule>
So if the URL is http://site.com/blog/whatevergoeshere. Ignore the blog part. and each split you just do {R:1} etc.. so if the url was http://site.com/blog/12/10/the-article-name and you want it to be http://site.com/articles/12/10/the-article-name is what the above does.

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