How to rewrite a URL without leaving the current page in C#? - c#

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>

Related

RouteConfig - IIS10+C# - Redirect Old Links

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>

Replace one word of domain URL in IIS

I moved my project to a new server (from abc.com/eco to abc2.com/eco) and created a HTTP redirect rule to redirect every abc.com/eco requests to abc2.com/eco. which works fine on abc.com/eco requests.
The problem is, Urls after eco does not get redirected.
For example:
abc.com/eco/departments/main.aspx?id=123
does not redirect to
abc2.com/eco/departments/main.aspx?id=123
The following Url rewrite rule doesnt work also:
<rule name="Redirects to abc2.com" patternSyntax="ECMAScript" stopProcessing="true">
<match url=".*" />
<conditions logicalGrouping="MatchAny">
<add input="{HTTP_HOST}" pattern="^abc.*(com|net)$" />
</conditions>
<action type="Redirect" url="http://abc2.com/{R:0}" />
</rule>
I looked over tens of questions but all are asking about the subdirectory replace.
Similar questions but not answering mine:
Question 1
Question 2
The rule is working properly on my side.
Have you cleaned cache before testing a new rewrite rule with long term permanent redirect.
If you didn't clean the browser cache, your previous HTTP redirection will keep redirecting your URL to http://abc2/eco

Redirect www to non www urls

My goal is to redirect all www.* urls to non-www urls. For example:
If the url is www.mydomain.com/users it should redirect to mydomain.com/users.
In order to achieve that I have written the following code in my web.config:
<rule name="Redirect www.* urls to non www" stopProcessing="true">
<match url="*" />
<conditions>
<add input="{HTTP_HOST}" pattern="^www$" />
</conditions>
<action type="Redirect" url="{HTTP_HOST}/{R:0}" redirectType="Permanent"/>
</rule>
but it does nothing and I can see the www urls not redirecting to non www urls.
Can you share what I am doing wrong there?
Do note that I don't want to add any hard coded domain in that rule. I want to make it generic.
I need a generic solution where in my rule there is no where a hard coded domain and a hard coded protocol is present.
Well, here is the solution I came up with.
I have provided the solution with all the details along with comments comments for the regex, capturing groups etc. used in the rule:
<rule name="Redirect www.* urls to non www" enabled="true">
<!--Match all urls-->
<match url="(.*)"/>
<!--We will be capturing two groups from the below conditions.
One will be domain name (foo.com) and the other will be the protocol (http|https)-->
<!--trackAllCaptures added for tracking Capture Groups across all conditions-->
<conditions trackAllCaptures="true">
<!-- Capture the host.
The first group {C:1} will be captured inside parentheses of ^www\.(.+)$ condition,
It will capture the domain name, example: foo.com. -->
<add input="{HTTP_HOST}" negate="false" pattern="^www\.(.+)$"/>
<!-- Capture the protocol.
The second group {C:2} will be captured inside parentheses of ^(.+):// condition.
It will capture protocol, i.e http or https. -->
<add input="{CACHE_URL}" pattern="^(.+)://" />
</conditions>
<!-- Redirect the url too {C:2}://{C:1}{REQUEST_URI}.
{C:2} captured group will have the protocol and
{C:1} captured group will have the domain name.
"appendQueryString" is set to false because "REQUEST_URI" already contains the orignal url along with the querystring.
redirectType="Permanent" is added so as to make a 301 redirect. -->
<action type="Redirect" url="{C:2}://{C:1}{REQUEST_URI}" appendQueryString="false" redirectType="Permanent"/>
</rule>
It will do the following redirects:
http://www.foo.com -> http://foo.com
https://www.foo.com -> https://foo.com
http://www.foo.com?a=1 -> http://foo.com?a=1
https://www.foo.com?a=1 -> https://foo.com?a=1

IIS Rewrite rule with Angular routing

I am building an application that is an ASP.NET MVC and Angular 1.x hybrid. I use MVC as a shell and then layered Angular on top of it. I did this for a couple of reasons. First, it provided me with the ability to create an HTML helper class for script references to support cache busting. Second, it allows me to "push" a set of server side configurations to angular for things like web service URLs, etc. All of this seems to be working ok except for a single issue.
Currently, I am having to process a couple of IIS rewrite rules to make all of this work properly. In testing in a staged environment today, I published a link to Facebook that does not appear to work properly though and I'm not really sure why. Based on my understanding of the rule syntax, I thought it would work, but isn't.
Here are the IIS rewrite rules I currently have in web.config and why I have each rule:
<system.webServer>
<rewrite xdt:Transform="Replace">
<rules>
<rule name="cachebust">
<match url="([\S]+)(/v-[0-9]+/)([\S]+)" />
<action type="Rewrite" url="{R:1}/{R:3}" />
</rule>
<rule name="baseindex" stopProcessing="true">
<match url=".*" />
<conditions logicalGrouping="MatchAll">
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
<add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
</conditions>
<action type="Rewrite" url="/" />
</rule>
<rule name="non-www" stopProcessing="true">
<match url="(.*)" negate="false"></match>
<conditions>
<add input="{HTTP_HOST}" pattern="^exampledomain\.org$" negate="true"></add>
</conditions>
<action type="Redirect" url="http://exampledomain.org/{R:1}"></action>
</rule>
</rules>
</rewrite>
</system.webServer>
1) The "cachebust" rule is used for script cache busting. The HTML helper I wrote takes the path of the script file and inserts a fake version # into the path. For example, "scripts/example.js" would become "scripts/v-123456789/example.js", where "123456789" are the ticks from the current date and time. This rule will rewrite the URL back to the original but since the page is output with the version stamped path, it will force my angular scripts to be reloaded by the browser in the event that they change. This rule appears to be working fine. Credit to Mads for this: https://madskristensen.net/blog/cache-busting-in-aspnet/
2) The "baseindex" rule is used to rewrite the URL so that ASP.NET will always serve the index.cshtml page that is used as the root for my site. This rule also appears to work fine. Credit to this SO QA: How do I configure IIS for URL Rewriting an AngularJS application in HTML5 mode?
3) The "non-www" rule is the problematic one. The goal of the rule is to redirect all www requests to non-www requests based on ScottGu's blog post (link below) about canonical host names and how they affect SEO. This rule works perfectly fine for www.example.org as it redirects the URL to example.org, but it fails when the URL looks like this: www.example.org/entity/1 where entity is a detail page for id = 1. In practice, it fails for www.example.org/about too.
Since my web services require CORS to be enabled as they are on separate domains, this also needs to happen for that.
https://weblogs.asp.net/scottgu/tip-trick-fix-common-seo-problems-using-the-url-rewrite-extension
For sake of completeness: HTML 5 mode is enabled for Angular and my route to the specified page is defined as such:
.state('entityDetail', {
url: '/entity/{id}',
templateUrl: 'app/pages/entity/entityDetail.html',
controller: 'entityDetailController',
controllerAs: 'entityDetailCtrl'
})
Also, my _Layout.cshtml contains the base href of:
<base href="/" />
and script references like such (except for the angular scripts that require the cachebust rule listed above):
<script type="text/javascript" src="scripts/jquery-2.2.0.min.js"></script>
I've tried several different versions of the rule, but they all lead to different issues. Since there are so many different things at play here, I am concerned that I am overlooking something or that I am wrong in my thinking on how this "should" work.
Any help would be greatly appreciated.
It took some trial and error to figure this all out, but wanted to post the answer I finally came up with in the event that someone else ever tries to marry ASP.NET MVC and Angular 1.x together while allowing cache busting in Google Chrome.
It turned out to be a couple of things:
1) The order of the rules.
2) The stopProcessing flag and when it should be enabled.
In summary, to get this to work, I built the rules so that all requests must be redirected to www.exampledomain.com and then stop processing rules until the reprocessed request happens (this time www. will be guaranteed). Then, the cachebust rule must happen BEFORE the rewrite to the base index of "/", otherwise, the entire HTML document is returned by the server when each of the script files that must be "busted" load. This was really the majority of my issue from the very beginning. The whole process was honestly a little confusing so if this answer is not sufficient, please comment and I will try my best to better articulate the "whys" I found in my research. Hope this helps someone else though...it only took 10 days to figure out. :)
<system.webServer>
<rewrite xdt:Transform="Replace">
<rules>
<rule name="forcewww" patternSyntax="ECMAScript" stopProcessing="true">
<match url=".*" />
<conditions logicalGrouping="MatchAny">
<add input="{HTTP_HOST}" pattern="^exampledomain.com$" />
</conditions>
<action type="Redirect" url="http://www.exampledomain.com/{R:0}" />
</rule>
<rule name="cachebust">
<match url="([\S]+)(/v-[0-9]+/)([\S]+)" />
<action type="Rewrite" url="{R:1}/{R:3}" />
</rule>
<rule name="baseindex">
<match url=".*" />
<conditions logicalGrouping="MatchAll">
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
<add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
</conditions>
<action type="Rewrite" url="/" />
</rule>
</rules>
</rewrite>
</system.webServer>
Instead of writing redirect rules in an app.config file, you can use the following in your Program.cs file:
var builder = WebApplication.CreateBuilder(args); // Followed by service configurations...
var app = builder.Build(); // followed by app configurations...
// The following will fix your redirect woes:
app.UseStaticFiles();
app.MapFallbackToFile("index.html");

URL Rewriting - Append page name along with query string in URL

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.

Categories