I use UrlMappings in web.config. Now, I must have 2 url entries to make the mapping work with both the trailing backslash and without. Like this:
<urlMappings>
<clear />
<add url="~/app" mappedUrl="~/Templates/Sections/Common/Article.aspx?id=981" />
<add url="~/app/" mappedUrl="~/Templates/Sections/Common/Article.aspx?id=981" />
</urlMappings>
Is it possible to make the url (~/app) work with or without trailing slash, in one line of code? Mabye by using wildcard or something for the "~/app" url..?
The urlMappings element doesn't allow for wildcards or regular expressions. A better solution for this problem would be the fully featured URL Rewrite Module (which is an optional module you can install in IIS) which do indeed allow you to write regex's to map your incoming URLs to an internal path.
Related
I'm having an issue with a rule being applied correctly on my site.
The rule is:
(^((?!\/bundles\/).)*[^\/]$)
The action is to append a slash to the end of this, using:
<action type="Redirect" url="{R:0}/" redirectType="Temporary" />
I try the following url:
http://example.com:9999/bundles/bundle.js
And IIS redirects me to http://example.com:9999/bundles/bundle.js/
But I go to IIS Manager, go to IIS Rewrite, select this rule, go to test, put the url in, click test, and it says that it's not a match.
If it's not a match, why is it still redirecting?
I created the same rule and it is redirecting. So, it is working as not expected: your rule (^((?!\/bundles\/).)*[^\/]$) match to http://example.com:9999/bundles/bundle.js
The problem in your rule. Correct rule is (^((?!bundles\/).)*[^\/]$). I removed slash before bundles. Because when request is coming into rule, it is comparing rule with path bundles/bundle.js (without starting slash)
Currently working with an external file for URL rewrites called rewritemaps.config (following these instructions), which works great. However, we have occasion to override an entry in that file with manual entries in web.config instead and they don't appear to work.
Specifically this issue has cropped up around the use of content experiments (A/B testing) with Google, which makes heavy use of querystrings in my URLs. The querystring takes the form of:
websiteurl.com/webpage1?utm_expid=########-#&utm_referrer=http%3A%2F%2Fwebsiteurl.com%2F
Now when attempting to validate my content experiment, I get the error
Web server rejects utm_expid. Your server doesn't support added query
arguments in URLs.
...which is true for that particular URL because in the rewritemaps.config file we have this line:
<add key="/webpage1" value="/somefolder/file.aspx?id=18" />
The rewrite rule works fine but no amount of manual entries in web.config seem to work. If I comment out the line in rewritemaps.config and attempt to reach /webpage1, it errors with 404..which is expected. But I try to use manual entries in my web.config like:
<rule name="test rewrite" stopProcessing="true">
<match url="^(https?:\/\/)?websiteurl.com\/webpage1(.*)*" />
<action type="Rewrite" url="{R:1}/somefolder/file.aspx?id=18" appendQueryString="false" />
</rule>
I'm placing the rewrite rule before
<rewriteMaps configSource="rewritemaps.config" />
I've added query_string conditions, appendQueryString to true and to false, nothing is working even if I use wildcard patternSyntax, so it's leading me to believe that I can't manually add rewrite rules into the web.config if there is an external rewritemaps.config file.
Is this true? If so, how can I manually override a rewrite rule because I have to add the ability to allow a querystring in a rewrite?
Well after much consternation and research, I stumbled upon this question and the highest voted answer, and it's working for me now with the rewrite rule still in rewritemaps.config.
Changing {REQUEST_URI} to {PATH_INFO}
In IIS 7.5 (Win2k8 R2) I'm trying to create a new rule for these requests:
http://www.domain.com/userprofile
https://www.domain.com/userprofile
http://domain.com/userprofile
https://domain.com/userprofile
rewriting to:
http://www.domain.com/users/?username=userprofile
(or whatever the protocol/domain is)
The regex that I wrote is:
^(http|https)://(www\.domain.com|domain\.com)/([a-zA-Z0-9-]{6,35})
and the rewrite is:
{R:1}://{R:2}/users/?username={R:3}
But this is not working. Is it because I don't need to the protocol? I also added conditions that the request is not a file or directory.
Also, do I need to restart IIS each time I change the rule?
You don't have to look at the protocol or domain name when you want to rewrite these request. It's not important in your case as you only want to rewrite the path.
The following rule should work:
<rule name="Rewrite user profiles">
<match url="([a-zA-Z0-9-]{6,35})" />
<action type="Rewrite" url="/users/?username={R:1}" />
</rule>
You don't have to restart IIS when you change the rule. IIS will automatically restart the application pool when web.config is modified and hence reload the rules.
#Marco was almost right, but here's how what ended up working: (I used the URL Rewrite form in IIS Manager)
Regex:
^([a-zA-Z0-9-]{6,35})(/?)$
Conditions:
Not a file
Not a directory
This forces the match to start directly after the domain and must be either the first directory, or with no trailing "/". According to the regex, the match must be between 6 and 35 characters, alpha numeric with "-"
I wish to canonicalize a domain name, from bar.example.com to www.example.com (well anything that's not www.example.com). Site runs IIS7.
The problem is that certain URLs were of the form http://bar.example.com/asp/oldpage.asp?query=awesome, and have specific URL rewrite rules already in place that redirect to http://www.example.com/newpage/awesome
I want to write a rule that catches the other rules.
HERE'S THE CATCH: I have a lot of rules, and want to put this rule in the root of the site, but have additional rewrite/redirect rules in sub-folders, so I want to defer the 301 from happening until all the rules have been run.
Is this possible? Rewrites have an option to defer (stopProcessing="false") but this doesn't seem to be an option for Redirects.
Am I SOL here?
Unfortunately, I can confirm that the deferred processing (stopProcessing="false") works with rewrite actions only and is ignored by the redirect ones.
Should the number of matches having been small - but it is not, according to your question - I would have suggested you to combine them using a regex alternation. For example:
First match: ^first/a$
Second match: ^second/b$
Combined match: ^(first/a|second/b)$
Leading to something like:
<rule name="MyCombinedRule">
<match url="^(first/a|second/b)$" />
<action type="Redirect" url="http://www.example.com/third/c" />
</rule>
I have:
<!-- Force lowercase URLS -->
<rewrite url="~/(.*[A-Z]+.*)$" to="~/handlers/permredirect.ashx?URL=${lower($1)}" />
Perm redirect simply 301 redirects to the new URL.
This rule is meant to redirect any URL with an uppercase char to the lower case one.
This however creates a redirect loop, any ideas why? The only rules running so far are:
<rewriter>
<!-- Remove Trailing Slash for all URLS-->
<rewrite url="~/(.*)/($|\?(.*))" to="~/handlers/permredirect.ashx?URL=${lower($1)}$2" />
<!-- Force lowercase-->
<rewrite url="~/(.*[A-Z]+.*)$" to="~/handlers/permredirect.ashx?URL=${lower($1)}" />
<rewrite url="~/construct2($|\?(.*))" to="~/construct2.aspx" processing="stop" />
</rewriter>
You can either modify the regular expression to exclude .ashx files (which might get extremely complicated) or create a new rule before this rule, that will catch URLs pointing to ashx files and redirect them to a lowercase version of the string.
Something like this might work (not tested):
<rewrite url="~/(?=(.*\.ashx.*))(.*[A-Z]+.*)" to="~/${lower($1)}" />
It uses a lookahead rule to check if ".ashx" is part of the url and if the URL is uppercase. If yes, it redirects to the lowercase version of the same url.