I am moving a website from a static website to MVC 5. I need to create controllers/actions to respond to requests with old URLs. ( and return a redirect, page moved ) If I just hardcode the old URL in attribute routing, I get
HTTP Error 404.0 - Not Found The resource you are looking for has been removed, had its name changed, or is temporarily unavailable
What is the best way of approaching this. ( what I mean is that how could I make a route for a url with .html extension, and ASP.net respond to it)
I think right now IIS sees that .html and tries to send the file to the client without going through the application. How could I remove that behavior on a shared hosting ?
the html files that are being served right now are in different folders.
example:
I need to map this URL to a controller/action:
example.com/services/Renovations.html
we will be mapping it to controller => services , and action => renovations
example.com/contactus.html
we will be mapping it to controller => contact , and action => index
Write your application using MVC Controllers/Actions as appropriate for your new architecture, then implement a set of URL Rewrite rules at the IIS level to map the old URL's to new ones. The Rewrite rules will be stored inside your web.config file which is handy for moving the configuration from Dev to Staging to Live environments.
If you give some examples of your old URL's and their new corresponding routes, I could give you some sample IIS Rewrite rules to match. This works best if your old URL's followed a pattern, e.g. /products/{skucode}.html etc
EDIT: Some sample rewrite rules to match the requested redirects.
<configuration>
<system.webServer>
<rewrite>
<rules>
<clear />
<rule name="Static rewrites" enabled="true" stopProcessing="true" >
<match url="^(.*?\.html)$" />
<conditions logicalGrouping="MatchAll" trackAllCaptures="false" />
<action type="Redirect" url="{static site rewrites:{R:1}}" appendQueryString="true" />
</rule>
</rules>
<rewriteMaps>
<rewriteMap name="Static site rewrites" ignoreCase="true">
<add key="contact.html" value="contact" />
<add key="services/renovations.html" value="services/renovations" />
</rewriteMap>
</rewriteMaps>
</rewrite>
</system.webServer>
</configuration>
It should be clear how to add more keys to the rewriteMap for other pages you'd like redirected. To clarify, these are Redirects and will return HTTP 301 Moved Permanently response codes to the browser and transparently redirect it to the new route.
Related
I have 2 distincts MVC Web Applications accessed from:
1) product.main-brand.com (solution landing page)
2) admin.product.main-brand.com (solution admin landing page)
The product is going to change the location from:
product.main-brand.com to www.main-brand-com/product
And the admin has to change from:
admin.product.main-brand.com to www.main-brand-com/product/admin
I can't create a Virtual Directory for the admin because www.main-brand-com/product is a controller.
For example, NopCommerce does that, we can go from www.shop.com to www.shop.com/admin and it's changing project and not controller/action. How does he do that?
Here are some steps to achieve a similar solution like in nopCommerce 3.9
Create your primary Web Project
Foo.Web
Properties
AssemblyInfo.cs
Foo.Web.csproj
Global.asax
Global.asax.cs
...
Create your admin Web Project inside of your primary Web project
Foo.Web
Administration
Properties
AssemblyInfo.cs
Foo.Admin.csproj
...
Administration folder must be created using "Add project wizard" or using explorer. Do not create that folder using solution explorer.
Remove Global.asax from admin project
You don't need this
Add an AreaRegistration implementation to your admin project
public class AdminAreaRegistration : AreaRegistration
{
public override string AreaName => "Admin";
public override void RegisterArea(AreaRegistrationContext context)
{
context.MapRoute
(
name: "AdminDefault",
url: "admin/{controller}/{action}/{id}",
defaults: new {controller = "Home", action = "Index", area = "admin", id = ""},
namespaces: new[] {"Foo.Admin.Controllers"}
);
}
}
Modify Global.asax.cs to register areas
Add this to your project. Make sure it's called before your default routes.
AreaRegistration.RegisterAllAreas();
With this, all your controllers inside of Foo.Admin are found by
~/Admin/{controller}/{action} and all your controllers inside Foo.Web
are found by ~/{controller}/{action}
Since you have 2 distinct MVC web applications I see 2 possible solutions...
a) create an Admin folder inside your main web application and set it as the root of your admin web application i.e. put your whole admin website into the admin folder. I expect this will require some tweaking of web.config of both apps so they can coexist.
b) leave each web application in it's own IIS virtual Application then add rewrite rules in the main web application for the /admin path to the true IIS path and you may need some rewrite rules in the admin app back to the main app if there is expected to be a navigation path to it.
I would recommend that you do look into attribute routing.
https://blogs.msdn.microsoft.com/webdev/2013/10/17/attribute-routing-in-asp-net-mvc-5/
This allows you to do this:
[Route("/product/admin")]
That attribute decorator goes on your controller method after you setup attribute routing.
Hope that helps.
This can easily be achieved in asp.net mvc application by using the feature called Area (for detail see https://learn.microsoft.com/en-us/aspnet/core/mvc/controllers/areas).
Your main application will work for www.main-brand-com. You can add an Area for Product to be referred by www.main-brand-com/product and another Area called Admin to be referred by www.main-brand-com/admin.
You can add an Area in asp.net mvc application by right clicking on web application project then selecting Add from the quick menu and then select Area. It will ask for name of Area to be created. After giving name and clicking Ok it will create an Area with that name in Areas folder in your web application project. The newly created Area will have same folder structure like main application like Controller, Model, View etc. folders. It will also create a class (AreaRegistration.cs) for registering the routing details for this Area. The content of this class may look like below code.
public class AdminAreaRegistration : AreaRegistration
{
public override string AreaName
{
get
{
return "Admin";
}
}
public override void RegisterArea(AreaRegistrationContext context)
{
context.MapRoute(
"Admin_default",
"Admin/{controller}/{action}/{id}",
new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
}
As a rule, if you're working with an externally maintained platform, you should aim to make as few code changes as possible. You will save yourself the work of merging, testing and deploying your code changes when there's an update. This is especially important if the update is a critical one.
In this particular case, it is best to let IIS to reroute your URLs. It has no code impact and offers a major benefit. Visitors and search using deprecated urls are automatically redirected to newer ones. This is especially important for search engines. If they encounter a 404 error, they will often remove the urls and even the entire site. In other words, VocĂȘ pode perder muitas vendas!
You can reroute your urls in the IIS Manager using the Url Rewrite Module or through web.config files. I recommend web.config files since it can be uploaded and kept together with your project.
For your existing product subdomain site, add the following to the system.webServer section of the site's web.config file:
product.main-brand.com to www.main-brand-com/product
<system.webServer>
<rewrite>
<rules>
<rule name="product.main-brand.com Redirect" stopProcessing="false">
<match url="^\/?$" />
<conditions>
<add input="{HTTP_HOST}" pattern=".*product\.main-brand\.com.*" />
</conditions>
<action type="Redirect" redirectType="Found" url="http://www.main-brand-com/product/{R:0}" />
</rule>
</rules>
</rewrite>
</system.webServer>
For your existing admin subdomain site, add the following to the system.webServer section of the site's web.config file:
admin.product.main-brand.com to www.main-brand-com/product/admin
<system.webServer>
<rewrite>
<rules>
<rule name="admin.main-brand.com Redirect" stopProcessing="false">
<match url="^\/?$" />
<conditions>
<add input="{HTTP_HOST}" pattern=".*admin\.product\.main-brand\.com.*" />
</conditions>
<action type="Redirect" redirectType="Found" url="http://www.main-brand-com/product/admin/{R:0}" />
</rule>
</rules>
</rewrite>
These addition will redirect users to the new URLs. Refer to the following article for how to setup IIS url rewrite for further information:
https://learn.microsoft.com/en-us/iis/extensions/url-rewrite-module/using-global-and-distributed-rewrite-rules
Changing the redirection in IIS is one part, but your application needs to understand how to route the new url scheme internally. Without your app's specific routing code, I can't be of much help. If your application, however, is using subdomain's url parameter and you want to change it, refer to the following article:
https://benjii.me/2015/02/subdomain-routing-in-asp-net-mvc/
I have an ASP.NET MVC (5) application and need to redirect urls such as
<domain>/london to <domain>/locations/london
I've defined a redirect in Web.config in system.Webserver
<rule name="london">
<match url="london" />
<action type="Redirect" url="locations/london" />
</rule>
When I run the site locally and browse to localhost:1111/london I get the following error
localhost redirected you too many times. ERR_TOO_MANY_REDIRECTS
What am I doing wrong?
I've spent some time looking online but can't find the answer...
your rule is basically saying if the URL contains London then redirect to locations/London. But locations/London contains the word London too so it will redirect again.
Try setting the rule to be
^london
(start with london)
We recently went through a major site redesign for an IIS 8, C# web site.
We have around 2 to 3 hundred old pages which needs to be redirected to new pages. All of them needs to be 301 redirects for SEO.
We are looking for some best practices to do this, without maintaining the physical files on the server.
IIS and .Net have several ways to do redirects.
In the code handing the request:
this.Response.RedirectPermanent("http://www.website.com/new-page/");
In the web.config file (probably the easiest way for you):
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<rewrite>
<rules>
<rule name="301 Redirect 1" stopProcessing="true">
<match url="^old-page\.htm$" />
<action type="Redirect" url="new-page" redirectType="Permanent" />
</rule>
<rule name="301 Redirect 2" stopProcessing="true">
<match url="^old-page2\.htm$" />
<action type="Redirect" url="new-page2" redirectType="Permanent" />
</rule>
</rules>
</rewrite>
</system.webServer>
</configuration>
It accepts regex so you can optimism this if the redirects have a pattern.
Finally you can take full control at a base level via the Routing Module (System.Web.Routing.UrlRoutingModule) and your own IRouteHandler.
Maintain a database of those URLS, that can be eventually loaded into memory at startup.
The 404 handler checks if the page exists in that database, and performs the redirect.
I don't know any solution for this... In sitecore or Umbraco there are some plugins to do this by example.
But it works great... If the old URL is replaced, then it will not be handled.
And you could extend that system even later, to maintain a database of all the urls invoked on your website ... Array of References (For Each Path Item): Url + Current URl, if for some reason you rename an item, then you can update your database with all URLS that contain some item.
How to do it:
When you access a certain page (like a folder), you can view information specific user, for example:
www.page.com/user001
Opens the default page www.page.com/userinfo.aspx in which that user get "user001" and display certain information. And the user see www.page.com/user001
I can do this with asp.net or IIS7?
something like subdomains
You can do this by adding the URL Rewrite Module to IIS. Check this out
http://www.iis.net/learn/extensions/url-rewrite-module/using-rewrite-maps-in-url-rewrite-module
You can store the URL Rewrite rules in the web.config file. For example:
<configuration>
<system.webServer>
<rewrite>
<rules>
****(Your URL Rewrite Rules)****
</rules>
</rewrite>
</system.webServer>
</configuration>
But if it's not possible for you to store it in web.config due to security or maybe for some performance issues, then you can store the URL Rewrite Rules in IIS.
I hope it helps.
you can use routing in global.asax file at application_start event instead of rewrite the url also this will redirect every this to the profile page
The website I work on hosts content that constantly gets scraped and posted elsewhere.
Is is possible to do URL rewrites so normal users and white-listed crawlers can view the website, but block access to unidentifiable browsers?
Yes, you can do that using URL Rewrite module (I'm using v2 .. but it should work with v1.x as well, although I have no v1.x around to test):
<system.webServer>
<rewrite>
<rules>
<rule name="UserAgentRedirect" stopProcessing="true">
<match url="^(.*)$" />
<conditions>
<add input="{HTTP_USER_AGENT}" pattern="(iphone|ipod)" />
</conditions>
<action type="Rewrite" url="/special-page.aspx" />
</rule>
</rules>
</rewrite>
</system.webServer>
With the above rule ALL requests from iPhone or iPad (or any other browser/app that has iphone or ipod in User Agent String) will be rewritten (internal redirect) to /special-page.aspx.
If someone really wants to scrape your content i guess its only a matter of time till he adapts his technice to fake an allowed browser. Still serving different content per user agent is a nice feature to explore.