How to 301 redirect - asp.net

Ok, I need to know how to do a redirect (where to put the code or specify the setting). We're redirecting from one app to another after we've moved the app.
So for example, if a user goes to existing.example.com/archive/
we want to redirect any requests that contain old.example.com to new.example.com. The rest in the url stays the same. So for example /archive/ is one example so we'd want to redirect them to the new location of this app which is new.example.com/archive/
I need to figure out how to check to see if the incoming URL to our existing site has existing.example.com, and if so replace that part only with the new new.example.com and keep the rest of what's in the url
I know you can do this in IIS 7 or programmatically. I guess I'm not understanding how to do this in either situation. I installed the IIS7 Rewrite plugin and ok fine, but here's what I don't get:
Pattern:
RedirectURL:
I don't see how in that interface I am able to match the existing.example.com and then what to put in the RedirectURL because I want to put the entire URL with only that existing.example.com changed to new.example.com in for the REdirectURL... and I don't see how I'd do this in IIS 7.

Here's a post describing how to match one domain and redirect to another with everything else in tact using the IIS7 URL Rewrite add-in: http://weblogs.asp.net/owscott/archive/2009/11/27/iis-url-rewrite-rewriting-non-www-to-www.aspx

You don't need any complicated rewriting stuff to do such a trivial redirect, it's a basic web server feature. In IIS7 you can now choose not to install it (from World Wide Web Services->Common HTTP Features->HTTP Redirection), but it would be unusual to do so.
Edit the ‘Bindings’ of the main web site in IIS Manager so that it only responds to the ‘Host name:’ new.example.com, then create a new web site bound to host name old.example.com. For this site hit the ‘HTTP Redirect’ option and ‘Redirect requests to this destination:’ http://new.example.com/ with ‘Status code:’ 301.
In config XML terms:
<system.webServer>
<httpRedirect enabled="true" destination="http://new.example.com/" httpResponseStatus="Permanent" />
</system.webServer>

In your site's global.asax.cs file you can redirect from BeginRequest as follows. You can write the routine to replace the domain names as needed with regex or string.replace() or whatever you prefer.
protected void Application_BeginRequest(Object sender, EventArgs e){
...parse urls...
Response.Redirect(myNewPath)
}

For asp.net applications, I've had good experience with urlrewriting.net, a free component where you can configure redirects in your web.config. It allows you to enter regular expressions and specify the new URL with back references, e.g. something like this (untested):
<add name="newdomain" virtualUrl="^http\://old.example.com/(.*)$"
rewriteUrlParameter="ExcludeFromClientQueryString"
destinationUrl="http://new.example.com/$1"
redirect="Domain"
redirectMode="Permanent"
ignoreCase="true" />
Drawback: This needs to be configured for every ASP.NET application (and you might need to reconfigure IIS to route everything through asp.net, or it might only work for .aspx files). If you want to redirect your complete domain, you are probably better off doing this on IIS level rather than on application level. For this, however, you might get better help on http://serverfault.com, which is where the sysadmins reside...

Related

Page Names: ASP.Net Web Forms Site, Deploying Multiple Languages

Sorry about the title, couldn't think of a good way to describe it briefly. On to the question...
I've written a site in ASP.NET using web forms and have used resource files to handle static text for multiple languages and our Database is setup for multiple languages, so everything is localized. It's as easy as switching culture and uiCulture in web.config to switch the site between French and English.
However, the french site has to be deployed with folders and page names translated to French. Example, http://www.product.com/accessories/category.aspx?id=111 needs to be http://www.produit.com/accesoires/categories.aspx?id=111
Aside from making copies of all the ASPX pages (not the code behinds), changing their names to the French equivalent and leaving their code-behind to point to the original aspx.cs... what is the preferred/proper/nice way to do this?
Please note: URLs referenced in the pages/code themselves are built dynamically so they will be localized as well.
Thank you!
Have you tried having a look at routing in asp.net? http://www.hanselman.com/blog/OneASPNETSneakPeekElegantWebFormsAndSnowballsInHell.aspx
I can't use routing as the server is running .NET 2.0 and routing wasn't introduced into the framework until 3.5 SP1. So I had to resort to URL rewriting.
In web.config I added:
<system.web>
<httpModules>
<add name="UrlRewriter" type="Utilities.UrlRewriter, MyProject"/>
...
<system.webServer>
<modules>
<add name="UrlRewriter" type="Utilities.UrlRewriter, MyProject"/>
I then created UrlRewriter which inherits IHttpModule, and in the Init method added a handler for HttpApplication.BeginRequest.
In BeginRequest I inspect the URL and replace localized folder names and page names with their English equivalent. For e.g. /mysite.com/a-propos-de-nous/ is converted to /mysite.com/about-us/ but the user still sees the French URL in their browser.
There's a bit of checking to do to convert the URL but it works well enough and the checking/replacing isn't horrid.
I have a couple quirks to figure out, if the URL comes in as /mysite.com/a-propos-de-nous (notice the missing '/' at the end) the rewrite works, but the URL in the browser address bar gets changed to /mysite.com/about-us which is not desired.
If any one has any additional thoughts, comments, or experience in localizing URLs please add to the thread.
[Edit - Feb. 28, 2013] - RE: lack of trailing slash in URL entered in browser
Adding this to make this more complete in case someone stumbles upon it.
The problem here is that IIS adds a courtesy trailing slash and this creates a redirect. To handle this case what I've done here is to inspect the URL and determine if it contains a page/file at the end of the URL. I use the following in my Url rewrite code:
void UrlRewriter_BeginRequest(object sender, EventArgs e)
{
HttpApplication app = (HttpApplication)sender;
... // other rewrite code here
string lastSegment = app.Request.Url.Segments[app.Request.Url.Segments.Length - 1];
string extension = System.IO.Path.GetExtension(lastSegment);
// no extension, must be a directory/folder
if (string.IsNullOrEmpty(extension))
{
if (!sendTo.EndsWith("/"))
sendTo = sendTo + "/";
}
app.Context.RewritePath(sendTo);
}

How to get Umbraco to handle requests for non .aspx files (IIS integrated pipeline mode)?

I'm trying to get the 301 URL Tracker package for Umbraco to work to my likings.
My goal is to be able to map the old URLs (from another CMS) to the new Umbraco URLs. In my specific situation, the old site is PHP based and therefore use the .php file extension (http://example.net/test.php -> http://example.net/test/) - but it could be any non .aspx extension (asp, png and so on). The problem is that Umbraco is not handling request for .php files. It works perfectly for .aspx and directories (extensionless URLs).
I have tried various things for getting this to work. Before I go any further, I should note that the Application Pool is in integrated mode and .NET 4.0.
I kind of got it to work by defining a custom error in the web.config:
<customErrors defaultRedirect="not-exists.aspx" />
This triggers the handlers defined in NotFoundHandlers in the Umbraco config file 404handlers.config. But has the side effect of returning a 302 Found header, before the 301 URL Tracker kicks in and handles the 301 redirect. And this is just a big SEO "no no".
I then tried to explicitly create a HTTP handler module for .php files. I successfully got the System.Web.UI.PageHandlerFactory module to handle the request for the .php file. But this does not invoke any of the NotFoundHandlers in Umbraco.
As I understand the integrated pipeline in IIS 7, all the modules registered should try to handle the request (http://stackoverflow.com/questions/3765317/how-to-catch-non-aspx-files-with-a-http-module). But perhaps somebody can enlighten me on this subject?
Others are also experiencing the difficulties in getting this configuration to work: http://our.umbraco.org/projects/developer-tools/301-moved-permanently/feedback/7271-when-the-old-pages-are-not-from-umbraco
What am I missing in getting Umbraco to handle request for non .aspx files in integrated pipeline mode?
If you are already running under Integrated Pipeline mode then the included UrlRewriting.net module should pick up requests automatically.
Simply add:
<add name="phptoaspx"
virtualUrl="^~/(.*).php"
rewriteUrlParameter="ExcludeFromClientQueryString"
destinationUrl="/$1.aspx"
ignoreCase="true" />
to your /config/UrlRewriting.config file, and all should be well.
P.S. You should not be using a customError handler to handle SEO 301/302'ing content. This can be a massive headache in terms of maintainability - please trust me on this, I tried this once when I was a junior .NET dev!
I am not familiar with Umbraco, but believe this is what you are looking for http://blogs.iis.net/ruslany/archive/2008/09/30/wildcard-script-mapping-and-iis-7-integrated-pipeline.aspx
Of course you'll have to add your own rewrite rules... so this only gets you half way.

Using IIS 7 Redirect Module or coding your own

What's the difference in using the IIS Redirect module to redirect vs. just coding your own and playing with the Response.context? To me it doesn't make a difference, they both do the same thing and it's much easier to just use the redirect module in IIS as it appears to redirect relatively anyway! Same as this code is doing in lets say a global.asax:
app.Response.Status = "301 Moved Permanently";
app.Response.AddHeader("Location", newLocation);
Am I not right? you can do the same thing 2 different ways! IIS or code! Using IIS just puts this into your app's web.config:
<httpRedirect enabled="false" destination="http://www.domainToRedirectTo.com/" exactDestination="false" httpResponseStatus="Permanent" />
nice and simple! exactDestination is false, so it will redirect relatively based off of the destination.
I want to hear arguments against using one way vs. the other because I don't see an argument that benefits either way. The both satisfy the same goal.
There is no difference in the way you have put it. A coded version allows you to react on input at runtime and use the code to redirect people to different pages --e.g., for a login.aspx page this might be a redirect to login-failed-page.aspx or login-succesfull-page.aspx. If its just hard-coded there is no difference.
Remember that redirects are not just meant to indicate permanent relocation of URL's. 301 is just one of the redirects. You may want to redirect people to a temporary message (redirect code 307) -- e.g., if you are working for apple and Steve Jobs is giving a keynote -- i.e., redirecting the store to a "Steve Jobs is giving a keynote and we are updating the store" page. In this example its far better to flick a switch and have your entire web-farm pick up the change via runtime logic than having to update the config files of all your IIS servers. Each redirect has its own purpose.

subdomain rewriting in ASP.NET?

How do i do this in .NET? http://why.does.my.head.asplode.net/ I want to do something like ytmnd where each url is a different user generated page. I might need something as simple as pointing to a directory so dirname.mysite.com will redirect to http_public/userGenContent/dirname/
I suggest you use UrlRewritingNet. You may have to add a rule similar to this:
<add virtualUrl="http://(.*).asplode.net/index.aspx"
rewriteUrlParameter="ExcludeFromClientQueryString"
destinationUrl="~/Users.aspx?username=$1"
ignoreCase="true" />
I cannot test this since I'm on a Linux machine right now, but it should work ;).
HAHA ...
I handled the Begin request event in global.aspx for this because my urls come from sql server.
Why are so many people sub domain crazy these days?
in Begin Request you can do something like this (not usre exactly because I aint got it in front of me right now) ...
request.rewriteurl( "new url" );
... this will take whatever the source url is and "redirect" without a redirect the response to a url you can use internally.
The various UrlRewriting tools will help you once you have the request getting into ASP.NET, however before that happens you need to setup IIS to pass these requests to your app. This is simple enough if there's only one app on the server, but more difficult otherwise.
Check out http://msmvps.com/blogs/bernard/archive/2005/03/22/39218.aspx for some details on wildcard subdomains on IIS.
Alternatively use an IIS level rewriter like ISAPI Rewrite
Essentially search for IIS wildcard subdomain to find a wealth of approaches.
Well, IIS7 has built url rewrite functionality. You can specify rules etc in web.config. But for IIS6 you need ISAPI dll that does the same for you. I've used IIRF and it works just fine.

URL Rewrite from /default.aspx to /

I'm using the URL Rewriting.NET tool with IIS 6. I've got my default page content set for default.aspx in IIS. What I'm trying to do is have /default.aspx provide a 301 redirect to the root directory (www.example.com/default.aspx -> www.example.com). I've tried turning off default documents, to no avail.
What I'm hoping to do is use a couple of URL Rewriting.NET rules to accomplish this goal. Any thoughts?
EDIT:
Sorry, I forgot to clarify. If I redirect from /default.aspx to / with default documents turned on (I'd like to leave them on) then I get an infinite loop of default -> / -> default
In the end I wound up using IIS 7 with the URL Rewrite module, which allows you to do this redirect properly.
Edit :
The rule is
<rule name="Default Redirect" stopProcessing="true">
<match url="^default\.aspx$" />
<action type="Redirect" url="/" redirectType="Permanent" />
</rule>
you can do that with a separate rule for each folder, or you can use
<rule name="All Redirect">
<match url="^(.*\/)*default\.aspx$" />
<action type="Rewrite" url="{R:1}" />
</rule>
I came across this very problem a while back while trying to work out why some IIS installs would work redirecting the /default.aspx and some would degenerate into a terminal loop.
I found the answer was whether or not asp.net was 'wildcard' mapped to run all requests within IIS.
Put simply, if you have an out-of-the-box IIS setup, it will always append the default document onto any request for the site root. Thus example.com becomes example.com/default.aspx when you inspect the Request.Url in ASP.NET. Therefore if you detect this situation and try to redirect away and back to example.com, IIS does so, appends the /default.aspx and your code is caught in a loop of it's own making.
The exception to this is if you set up wildcard mapping so that all requests are processed through the asp.net pipeline. In this case, IIS no longer appends the default document onto each request at the Request.Url level. And thus you can do the redirect.
I put it all in this blog post : 301 Redirecting from /default.aspx to the site root - the final word - but this was written several years back and changes in IIS7 may have fixed the problem, as the currently accepted answer provides.
But if you're battling this problem, then looking at the wildcard mapping status is the right place to start.
I had the same problem. For those who wonder why anyone would want to do this, it's a question of SEO. If Google indexes your home page with and without the default.aspx at the end, the PageRank and link popularity will be split between the two URL's. Now, if you're experiencing this problem, and you're able to consolidate the two URL's then you may get a boost in search rankings. One more thing to keep in mind is that if you're going through the trouble, you MUST use a 301 redirect for Google to consolidate their index between two URL's. Otherwise your efforts will be futile.
This is a little too late since you've already solved this by upgrading to IIS7. But I'll just add that the only solution to this problem I've come up with for IIS6 is to add an ISAPI filter.
I documented the complete solution here...
http://swortham.blogspot.com/2008/12/redirecting-default-page-defaultaspx-to.html
If I understand you correctly, you don't want to display 'default.aspx' whenever someone comes into a folder with that document available.
So if they do hit it, you want to automatically redirect to the '/' and just load the default document anyway?
If that's the case then, as stated above, you run the risk of an infinite loop. The second comment gives you an answer but I guess expanding that to the re-write engine what you'd want is to:
Turn off default documents
Register each folder with the re-write engine
When that folder is requested load the default.aspx file as per your target rule
Does this sound about right?
I have to ask, why do you want to do this?
I'm not sure I understand what the problem is.
Though if you turn off default documents then / will simply point to the directory rather than the default.aspx page.
Leave default documents on and just do a redirect based on whether default.aspx is in the requested url or not.
well you can use regular .net to inspect httprequest url, if it has "default.aspx" in it, you can redirect to "/", there will be no infinite loop and you better do this on preload, and end response afterwards, to minimize time it takes to process

Resources