Globally modify left part URL in MVC 4 / 5 - asp.net-mvc

I am using IIS 8.5 with MVC4 and MVC5.
Let´s assume that I have two websites where the URL of the first (WS1) is:
http://myapp.example.com
and the second website (WS2) URL is:
http://myapp.example.com/sub
(and is located on another port to which I want to forward)
Now, my problem is that all URLs generated by MVC (links etc) will use the left part of the URL and remove /sub within that application. Let´s say for instance that in WS2 I want to redirect the user to http://myapp.example.com/sub/login but it will become http://myapp.example.com/login instead.
I have tried IIS URL rewrites but it will only work first-time request that actually contain the /sub part, the URLs generated by MVC of course remains erroneously without the /sub part.
<rewrite>
<rules>
<rule name="Rewrite">
<match url="^Sub/(.*)" />
<action type="Rewrite" url="http://myapp.example.com/{R:1}" />
</rule>
</rules>
<outboundRules>
<rule name="Response Status Update" preCondition="ResponseStatus" stopProcessing="true">
<match serverVariable="RESPONSE_Location" pattern="^/(.*)" />
<action type="Rewrite" value="/Sub/{R:1}" />
</rule>
<rule name="RewriteRelativePaths" preCondition="IsHTML">
<match filterByTags="A, Area, Base, Form, Frame, Head, IFrame, Img, Input, Link, Script" pattern="^/(.*)" negate="false" />
<conditions>
<add input="{URL}" pattern="^/Sub/.*" />
</conditions>
<action type="Rewrite" value="/Sub/{R:1}" />
</rule>
<preConditions>
<preCondition name="IsHTML">
<add input="{RESPONSE_CONTENT_TYPE}" pattern="^text/html" />
</preCondition>
<preCondition name="ResponseStatus">
<add input="{RESPONSE_STATUS}" pattern="3[0-9][0-9]" />
</preCondition>
</preConditions>
</outboundRules>
</rewrite>
My question is how I can accomplish this. Using another subdomain is not an option.

Related

URL Rewriting using web.config file in .net MVC Application

I want to write a rule in web.config so that I can redirect URL.
Only for this keyword in URL(/resultprocess/). I want to change domain in URL.
My input URL is : http://A.B.C.D:8082/resultprocess/GetMessage (having any type of input data).
I want output URL : http://M.N.O.P:9092/resultprocess/GetMessage (with same input data).
I have tried follownig rules:
<rewrite>
<rules>
<rule name="Rewrite Rule2">
<match url="/resultprocess(.*)" />
<conditions>
<add input="{URL}" pattern="/resultprocess(.*)" />
</conditions>
<action type="Redirect" url="http://M.N.O.P:9092/{R:0}"/>
</rules>
</rewrite>
But it's not working. Please suggest me, what am I doing wrong?

IIS Rewrite and reverse proxy for multiple applications

I have an IIS 10 with a website configured on that. There are multiple Applications underneath that website.
MyWebsite/app1 - MyWebsite/app2 - MyWebsite/app3
I Have another server(let's call it EndServer) hosting 3 websites on 3 different ports.
well, now what I wanna do is using IIS as a reverse proxy to redirect and MASK the application 1 to one of those websites in 2nd server and application 2 to another one.
at the end, Users will enter https://mywebsite/app1 and they will see the contents of website 1 in the Endserver.
Note: it is important for me that end Users see the URL like as https://mywebsite/app1/
how shall I edit the Rule below:
<rewrite>
<rules>
<rule name="ReverseProxyInboundRule1" stopProcessing="true">
<match url="(.*)" />
<action type="Rewrite" url="http://endserver:8052/{R:1}" />
<conditions trackAllCaptures="true">
</conditions>
</rule>
</rewrite>
Thanks
A.
According to your description, I suggest you could try to use below url rewrite rule.
<rule name="ReverseProxyInboundRule1" stopProcessing="true">
<match url="(.*)" />
<conditions trackAllCaptures="true">
<add input="{URL}" pattern="^/app1/(.*)" />
</conditions>
<action type="Rewrite" url="http://endserver:8052/{C:1}" />
</rule>
<rule name="ReverseProxyInboundRule2" stopProcessing="true">
<match url="(.*)" />
<conditions trackAllCaptures="true">
<add input="{URL}" pattern="^/app2/(.*)" />
</conditions>
<action type="Rewrite" url="http://endserver:8053/{C:1}" />
</rule>
Thanks for your answer.
I got same error. as you see below /App1 is missing in the URL after localhost:Port
localhost:8888/assets/styles/Custom.css?m=1549903616.0
I believe the trouble is with rewriting the response URL. I don't know who can I add the missing part in URL.
Regards.

IIS Rewrite module - how to redirect maintaining path and querystring but adding an extra querystring parameter?

I've been banging my head against a brick wall attempting to get some IIS redirect rules to work. I've searched and read stuff here on Stack Overflow and on IIS.net but it just doesn't work at all.
I'm trying it on my local (real) IIS, I have the rewrite 2.0 module installed and have tried doing a repair install on it. I've done an iisreset at an admin cmd line more times than I care to mention.
In my hosts file I have set-up 127.0.0.1 for the URL my.test.com.
What I want to achieve is given a sub-domain URL redirect to the main domain URL with an extra querystring parameter whilst maintaining the existing path and querystring values if they exist.
I setup 3 rules as follows that are in the root folder of the website:
<system.webServer>
<rewrite>
<rules>
<rule name="PathAndQueryString" enabled="true" stopProcessing="true">
<match url="(/\w*)(\?\w*=\w*)([&\w*=\w*]*)" />
<action type="Redirect" url="https://www.test.com{R:1}{R:2}{R:3}&param=value" appendQueryString="false" />
<conditions logicalGrouping="MatchAll" trackAllCaptures="false">
<add input="{HTTP_HOST}" pattern="my.test.com" />
</conditions>
</rule>
<rule name="Querstring" enabled="true" stopProcessing="true">
<match url="(\?\w*=\w*)([&\w*=\w*]*)" />
<action type="Redirect" url="https://www.test.com{R:1}{R:2}&param=value" appendQueryString="false" />
<conditions>
<add input="{HTTP_HOST}" pattern="my.test.com" />
</conditions>
</rule>
<rule name="DomainOnly" enabled="true" stopProcessing="true">
<match url=".*" />
<action type="Redirect" url="https://www.test.com?param=value" appendQueryString="false" />
<conditions>
<add input="{HTTP_HOST}" pattern="my.test.com" />
</conditions>
</rule>
</rules>
</rewrite>
</system.webServer>
Unfortunately despite testing the patterns and confirming the {R:x} captures are correct when I try to test this using Edge, Chrome, Firefox and IE for all of them IIS acts like the rules don't exist.
Tests:
https://my.test.com >> https://www.test.com?param=value
https://my.test.com/SomePath >> https://www.test.com/SomePath
https://my.test.com/SomePath?AParam=AValue >>
https://www.test.com/SomePath?AParam=AValue&param=value
None of the above tests work, they get served without a redirect.
I've also tried putting the condition pattern used as part of the Match URL pattern but it didn't work with that either; in fact I moved it to the condition after reading a Stack Overflow post which said when rules are in the root of the site it doesn't include the host, but still nothing works.
Any help would be much appreciated.
UPDATE 1: For the path and querystring rule tried removing the bolded part from that start of this pattern (/\w*). Didn't have any effect.
UPDATE 2: Tried enabling the extremely temperamental "Failed Request Tracing" functionality and when it is actually working it says that none of the Match URL patterns are matching, except for the 3rd rule which has now started kicking in and redirecting but is not maintaining the path and other querystring params for obvious reasons.
UPDATE 3: On Edge and IE none of the rules work at all. On Chrome and FF the domain only redirect appears to be working - however if I disable the domain only rule and restart IIS it acts as though the rule is still there - FFS give me strength this crap is really starting to boil my blood now - this should not be that damn difficult.
Before I give the answer, a shout out to Yuk Ding at Microsoft who responded to a copy of this post on the iis.net forums and provided most of the answer.
So here we go, if you want rewrite rules that redirects from 1 URL to another maintaining the path and querystring if they exist whilst at the same time adding on a hardcoded URL parameter with the appropriate & or ? then here are the rules you will need.
In the rules you are redirecting from my.test.com to www.test.com, but obviously you would need to replace those 2 URLs in the rules below as well as changed the hardcoded parameter "ExtraParam=SomeValue" to what you need.
<system.webServer>
<rewrite>
<rules>
<rule name="DomainOnly" enabled="true" stopProcessing="true">
<match url="(.*)" />
<conditions trackAllCaptures="true">
<add input="{HTTP_HOST}" pattern="my.test.com" />
<add input="{REQUEST_URI}" pattern="/.+" negate="true" />
</conditions>
<action type="Redirect" url="http://www.test.com?ExtraParam=SomeValue" redirectType="Temporary" />
</rule>
<rule name="PathOnly" enabled="true" stopProcessing="true">
<match url="(.*)" />
<conditions trackAllCaptures="true">
<add input="{REQUEST_URI}" pattern="/.+" />
<add input="{REQUEST_URI}" matchType="Pattern" pattern="\?.+" ignoreCase="true" negate="true" />
<add input="{HTTP_HOST}" pattern="my.test.com" />
</conditions>
<action type="Redirect" url="http://www.test.com{C:0}?ExtraParam=SomeValue" redirectType="Temporary" />
</rule>
<rule name="Querstring" stopProcessing="true">
<match url="(.*)" />
<conditions trackAllCaptures="true">
<add input="{REQUEST_URI}" pattern="/.+" />
<add input="{QUERY_STRING}" pattern=".*" />
<add input="{HTTP_HOST}" pattern="my.test.com" />
</conditions>
<action type="Redirect" url="http://www.test.com{C:0}&ExtraParam=SomeValue" appendQueryString="false" redirectType="Temporary" />
</rule>
</rules>
</rewrite>
In my eyes the URL Rewrite 2.0 module has a bug. The basic crux is that you cannot match anything in the main match pattern you have to do everything with conditions. Thus the fact that you can set a pattern for the match is completely pointless because if you try to match anything other than (.*), i.e. match anything like I originally did it won't do what you want and will effectively cause head-bashing-brick-wall-ness.
The even more annoying thing is that in IIS Manager the UI for this is very unhelpful. You can test your patterns - and I did - and they will work, but all it's really testing is the regEx pattern.
What we really need is a test at the rules level. In other words you enter a URL and it tells you whether any of the rules match and which conditions pass or fail. Yes you can get this information if you enabled the failing request tracing rules but it's all a long winded phaff to enable and works in a haphazard fashion (just try clearing out the old logs and watch as it then stops logged until you turn it off and on again) for something that should be trivial.

IIS Rewrite Module and sub applications

Here's what I have deployed:
testRedirect is an empty website. All sub-applications are sub-folders that have been converted in application. All of them are ASP .Net MVC sites.
Here's what I want to setup:
Http://localhost/ must show the content of SiteName1 without
displaying Http://localhost/SiteName1/ in the adress bar (it must
stay Http://localhost/)
Http://localhost/SiteName1/ must show the content of SiteName1
without displaying Http://localhost/SiteName1/ in the adress bar
(it must stay Http://localhost/)
Http://localhost/SiteName2/ shows the content of SiteName2 and
displays Http://localhost/SiteName2/ in the adress bar (Same behavior for SiteName3 & SiteName4 and any other sites....)
In other words, I want my SiteName1 to act like a home site
What I've tried so far, is something similar to the answer provided by #cheesemacfly here:
<rules>
<rule name="Redirect if SiteName1" stopProcessing="true">
<match url="^SiteName1/(.*)$" />
<action type="Redirect" url="{R:1}" />
</rule>
<rule name="Rewrite to sub folder">
<match url="^.*$" />
<action type="Rewrite" url="SiteName1/{R:0}" />
</rule>
</rules>
It works great for Case1 & 2 but not the other ones.
I tried to add rules like this one, but it was not successful...
<rule name="if_not_SiteName1" stopProcessing="true">
<match url="^SiteName1/(.*)$" negate="true" />
<action type="None" />
</rule>
I think your best option would be to trigger the rewrite rule you already have only when the url doesn't start with one of your sub-applications.
It would be something like:
<rules>
<rule name="Redirect if SiteName1" stopProcessing="true">
<match url="^SiteName1/(.*)$" />
<action type="Redirect" url="{R:1}" />
</rule>
<rule name="Rewrite to sub folder">
<match url="^(SiteName2|SiteName3|SiteName4)/" negate="true" />
<action type="Rewrite" url="SiteName1/{R:0}" />
</rule>
</rules>
We keep the redirect when SiteName1/ is requested (we don't need to change this), but the rewrite rule is triggered only when the requested url doesn't start with SiteName2/ or SiteName3/ or SiteName4/ (that's what url="^(SiteName2|SiteName3|SiteName4)/" means and we use negate="true" to triggered the rule only when the pattern is not matched).

URL Re-writing using web.confg

This is what I'm trying to achieve using web.config (My current web.config is used to force non-www which will still be needed)
The site was first hosted under a sub-folder and we moved it now to the root. This is what I'm trying to achieve now:
old url example: mysite.com/subfolder/prodView.asp?idproduct=1312&idCategory=44 should get redirected to mysite.com/prodView.asp?idproduct=1312&idCategory=44 (We need to get rid of the old subfolder)
This is will be needed as many customer have already saved products link in their browsers and also we posted 1000's on links on twitter and facebook that all include the sub-folder within.
Any help will be highly appreciated.
Current web.config
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<rewrite>
<rules>
<rule name="Remove WWW prefix" stopProcessing="false">
<match url="(.*)" ignoreCase="true" />
<conditions>
<add input="{HTTP_HOST}" pattern="^www\.mysite\.com$" />
</conditions>
<action type="Redirect" url="http://mysite.com/{R:1}" redirectType="Permanent" />
</rule>
</rules>
</rewrite>
</system.webServer>
</configuration>
Add the following rule to your existing rule(s):
<rule name="Redirect old subfolder links" stopProcessing="false">
<match url="^subfolder/(.+)" ignoreCase="true" />
<action type="Redirect" url="/{R:1}" appendQueryString="true" redirectType="Permanent" />
</rule>

Resources