Given a URL rewrite rule like the following:
<rule name="RewriteUserFriendlyThings" stopProcessing="true">
<match url="^cat/sub-cat/(\d+)/([^/]+)/?$" />
<conditions>
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
<add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
</conditions>
<action type="Rewrite" url="cat/sub-cat/detail.aspx?id={R:2}" />
</rule>
In C# code I need to read out the value in the second group of the pattern (which is my ID) for my Bookmark button (don't ask) to work with pages that are dynamic like this. I'm using a certain CMS which does things at publish time, and we missed out bookmarking dynamic content.
So what I've done is load the web.config as XML and match the current URL based on what is in the url attribute of the match element. However, I can't figure out how to get at the group. Bearing in mind this needs to be generic so in another rule the group could be the third or first group.
I have a white list of rules which I do this against.
I tried using Capture Groups (?<id>\d+) but the web.config doesn't allow them.
The way I've got around this is using the Server Variables feature of the IIS 7 URL Rewriting module.
I defined a new allowed server variable and then captured the value that I needed that way using the IIS URL Rewrite syntax {R:2}. I could then acccess the value using the HttpContext.Request.ServerVariables collection.
The idea of using named groups seems like a reasonably good way to address the flexibility of the rules. I don't currently have access to testing rewrite rules on IIS but you might want to try using the alternate approach to name captured groups. Maybe that will get through.
Try this alternate pattern instead, which uses single quotes in place of the angle brackets:
(?'id'\d+)
Related
Good evening,
I'm pretty new on C# and IIS, and I am trying to figure it out about FriendlyUrls.
I guess I'm doing good but, I have an issue.
Let's say that today my site has all the pages in the /Pages folder so that an URL would be:
https://www.foo.xyz/Pages/my-dog.aspx
With the default FriendlyUrls installation, a user using that link, would see this in his browser:
https://www.foo.xyz/Pages/my-dog
And that is really ok, but not enough yet.
With this piece of code:
routes.MapPageRoute("FirstLevel", "{file}", "~/Pages/{file}.aspx");
Every new url www.foo.xyz/my-dog would point to the same file /Pages/my-dog.aspx.
So, I will keep on using the previous files.
But now... I would like to to tell a browser or a spider that all previous links made like /Pages/foo.aspx are permamently moved (301) to the brand new link.
Is it possible to do that via code? Or do I need to use the IIS url rewrite module and keep the business logic in the web.config file?
Thanks in advance
You can easily achieve that with URL rewrite rule.
<rule name="rewrite" stopProcessing="true">
<match url="(.*)" />
<conditions>
<add input="{URL}" pattern="^/Pages/(.*)\.aspx" />
</conditions>
<action type="Redirect" url="Pages/{C:1}" />
</rule>
I want to add some URL rewriting stuff in my web.config
The source URL:
http://constant.com/caam/verifying/?token=kpG1TwYo2KqTS%2bKg%2fY6lVm2Gt
Need to convert it to URL:
http://constant.com/caam/verifying/default.aspx?token=kpG1TwYo2KqTS%2bKg%2fY6lVm2Gt
Any ideas on how to accomplish this or other suggestions much appreciated it.
A basic redirect rule in IIS (web.config) might look like:
<rule name="Token Redirect" stopProcessing="true">
<match url="caam/verifying.*" />
<conditions trackAllCaptures="true">
<add input="{QUERY_STRING}" pattern="&?(token=[^&]+)&?" />
<add input="{REQUEST_URI}" pattern="default.aspx" negate="true" />
</conditions>
<action type="Redirect" url="/caam/verifying/default.aspx?{C:1}" appendQueryString="false" redirectType="Found" />
</rule>
You can change the match url, but basically this is matching everything that starts caam/verifying.
It then (additionally) checks that the query string has "token=" in it somewhere, and captures its value (it will go into the capture 1 as there's nothing else here, eg {C:1}).
We then output the redirect as /caam/verifying/default.aspx?{C:1} (where {C:1} is "token=12345", for example).
Note that this rule will only get hit if the URL matches (the caam/verifying part) and the parameters match (there's the "token=" part) - this redirect rule gets skipped otherwise.
EDIT
I've added an additional "negate" rule to not match against the "default.aspx" page.
Using Url Rewrite module, I want to drive a rewrite based upon some value retrieved during a custom authentication process.
During the PostAuthenticateRequest I attempt to set the HTTP header with HttpContext.Current.Request.Headers.Add("name", "value"); which is visible on the request object before it leaves the HTTPModule.
However in the URL Rewrite, a very basic condition fails since there's no text under the HTTP_name.
<rule name="customrule" enabled="true" stopProcessing="true">
<match url="(.*)" />
<conditions logicalGrouping="MatchAll" trackAllCaptures="false">
<add input="{HTTP_name}" pattern=".+" /> <!-- doesn't work -->
<!-- <add input="{HTTP_name}" pattern=".*" /> works -->
</conditions>
<action type="Rewrite" url="https://someotherdomain/{R:0}" />
</rule>
Changing the pattern on the condition to .* lets the rule pass but the URL comes out as https:///{R:0}. If I manually add the name Header before requesting the resource from the server it is able to find data. Unfortunately I don't have the data on the until after a request is made.
Can I use headers across the IIS modules? How can I get the value from the PostAuthenticate to the URL Rewrite?
Per this blog http://blogs.iis.net/wonyoo/relationship-between-application-request-routing-and-url-rewrite-modules the ARR implementation occurs at some point after the URL Rewrite and is the actual proxy for external servers.
As I understand it, the Url Rewrite module pulls the headers early on in the request pipeline. As such the Url Rewrite module wouldn't have access to the headers. The pipeline continues to execute through Authentication & PostAuthentication and eventually hands over to Application Request Routing the responsibility to be the proxy.
I want to Re-write my URL without leaving the current.
I find large number of post related to URL Re-writing, but i did'n get success.
I want if user enter this URL -
http://localhost:16185/Company/CareerWebsite.aspx?org_name=hire-people
URL automatically convert into this format -
http://localhost:16185/hire-people
but the original page (Company/CareerWebsite.aspx?org_name=hire-people) does not leave.
Means, user did't see the original URL(Company/CareerWebsite.aspx?org_name=hire-people) in browser. User can only see virtual URL like /hire-people.
Thanks for help...!!!
Well, if you want to do it directly same way as you described you need to do Redirect 301 or 302. For url-rewriting you'l probably need to install urlRewrite module for iis.
So far you'l need some kind of following url-rewrite rule in web.config file:
<rule name="RedirectUserFriendlyURL1" stopProcessing="true">
<match url="^Company/CareerWebsite\.aspx$" />
<conditions>
<add input="{QUERY_STRING}" pattern="^org_name=([^=&]+)$" />
</conditions>
<action type="Redirect" url="{C:1}" appendQueryString="false" />
</rule>
I have the url:
http://primarydomain.com/sites/secondarydomain/?foo=bar
What regex expression could I use to match the url for sites/secondarydomain - not case sensitive (this is for a rule in a web.config file but requires standard regex)?
To put it into context, I am writing a web.config url rewrite rule to remove sites/secondarydomain from all urls (due to a multiple sites being hosted on the same package).
<rule name="Remove full hosting path">
<match url="***Regex goes here***" ignoreCase="true"/>
<action type="Redirect" url="http://secondary.com/{R:1}" redirectType="Permanent" />
</rule>
I am looking to match only the directories (not the query string) in order to redirect the user (hence removing the sites/secondarydomain).
Update: It looks like I want to rewrite the url and not redirect, here is the current web.config rule that doesn't quite work:
<rule name="TestRule">
<match url=".*" />
<conditions>
<add input="{PATH_INFO}" pattern="^(/hostedsites/clemones_htdocs)(/.*)"/>
</conditions>
<action type="Rewrite" url="\{C:2}" appendQueryString="true" />
</rule>
Where my secondary domain is http://clemones.com/
and the path I'm trying to get rid of: http://clemones.com/hostedsites/clemones_htdocs/
FOR testing, http://clemones.com/shizzle works as a destination (hence sadly http://clemones.com/hostedsites/clemones_htdocs/shizzle also works).
Thanks in advance
Have you tried:
To elaborate, this only applies the regex to the path, not the root url:
<rule name="TestRule">
<match url=".*" />
<conditions>
<add input="{PATH_INFO}" pattern="^(/sites/secondarydomain)(/.*)"/>
</conditions>
<action type="Rewrite" url="\{C:2}" appendQueryString="true" />
</rule>
There are multiple groups resulting from the condition, {C:2} represents everything that comes after "/sites/secondarydomain/", excluding the query string which is appended by choosing "appendQueryString=true".
It allows you to break out the parts you want to take action on, so yes it is different than just applying a regular expression to the entire url.
Here is an article that explains how this works:
http://weblogs.asp.net/owscott/archive/2010/01/26/iis-url-rewrite-hosting-multiple-domains-under-one-site.aspx
Try a lookbehind (?<=(http://primarydomain.com/))[^\b]*
EDIT:
If you want to exclude the querystring... (?<=(http://primarydomain.com/))[^?]*
If you want to be more strict for whatever reason (like only allowing alphabet characters in the directory), you can try something like this (?<=(http://primarydomain.com/))[a-zA-Z/]*[a-zA-Z]
if the domain is always going to be http://primarydomain.com/sites/ then I would attack it like this:
match url="http://primarydomain.com/sites/([A-Za-z0-9_]+)/.*";
A combination lookbehind and lookahead will match the string you want:
(?<=.\w+/)\w+/\w+(?=/.*)
That being said, the {R:1} in your example really looks like a Regex backreference, so maybe that's why things aren't working as expected. If this is true, you may need something like this instead:
.\w+/(\w+/\w+)
Never done IIS rewriting, so YMMV. The two regular expressions do work (tested) on the examples you've given so far, and more generic URLs like:
http://primarydomain.com/hostedsites/clemones_htdocs/index.aspx?foo=bar
http://anydomain.net/sites/secondarydomain/index.aspx?foo=bar
...