I have some routes in my ASP.NET MVC application that handle redirecting of old urls. The URL I'm redirecting is:
contentSpanishContentList.aspx
Here's the route:
routes.MapRoute("RedirectLegacyContent1",
"content{contentUri}.aspx",
new { controller = "Redirect", action = "Content", contentUri = string.Empty, contentId = 0 });
The problem is it comes up as not found. I figured out that the problem is (in bold) contentSpanish*Content*List.aspx. What should I do to make this route work with this case?
Two solutions
Rename your pages to not include the same constant string (in your case it's the word content).
Write a custom route that's able to parse your requests - all you'll have to override is the GetRouteData method. And if you're planning to only use this route for incoming requests (not generating any URLs in your views to point to any of these pages ie. using Url.Action or Html.ActionLink) then the easiest way would be to generate something like a RegExRoute which would be easy to write and also easy to resolve these kind of requests.
The fist one is simple, the second is universal.
Use Fiddler to look at what's happening. Is the 404 happening on the first request? Or is it happening after the redirect?
Install the RouteDebugger package and see what it tells you.
Related
Okay, here's the deal:
I have an aspx page that looks like mysite.com/UnitDetails.aspx?UnitID=123
Right now I've setup my routing to be able to take in something like mysite.com/My/Path/123 and redirect it to UnitDetails.aspx. This works great.
However, what I'd like to be able to also do is redirect the user to the clean url if they type in the aspx page. For example, if you have mysite.com/UnitDetails.aspx?UnitID=123 bookmarked, I'd like it to show up as mysite.com/My/Path/123.
How can I accomplish this? Here's what I have right now in my routing:
RouteTable.Routes.MapPageRoute("unit_details", "{area}/{property}/{unit_id}", "~/UnitDetails.aspx")
Okay, I figured it out!
Just needed to add this into my UnitDetails.aspx code behind in the Page_Load:
//issue a 301 if legacy route requested to boost SEO
if (Request.Url.AbsolutePath.Contains("UnitDetails.aspx"))
{
var unit = BeachGuide.Models.Unit.GetById(Convert.ToInt32(Request.Params["UnitID"]));
Response.RedirectPermanent(unit.relative_url);
}
So now if they request the new url, they won't get caught in an infinite loop. If they request the old url, we have a base case that redirects them to the new url via a 301 redirect. This will help search engines know to use the new route as the canonical url.
I am struggling with routing issues in my ASP.NET MVC + WebAPI app. I feel like I have a moving target here because when I add or change one route I break another. Here is my specific example.
First, my controllers, so you can see the names:
Next, my MVC routing config (I understand that my config is probably duplicative, but it is because I am trying things):
And my Web API routing config (I understand that my config is probably very duplicative, but it is because I am trying things):
As a routing problem example, here's the PodcastFeeds API controller:
So I post to the Create action method...
And as you can see I get the error: 404 not found - "No HTTP resource was found that matches the request URI.
I would love some direction here...
The order or registering routes is important since requests are handled by the firs route that matches the patter. Because your default route is the first one it always selected. You need to put your default route to be the last one and register all your routes starting from the most constraining and ending with default one. Also Is I see in your screenshots some of your routes are not fully configured: for example api/PodcastFeeds route doesn't specify a controller (it needs to look similar to your FeedRouteMap route from the second screenshot):
routes.MapHttpRoute(
name: "PodcastFeeds",
url: "api/PodcastFeeds/{action}/{id}",
defaults: new {controller="PodcastFeeds", action="Create", id=UrlParameter.Optional})
As an alternative you can use attribute routing to avoid those kind of issues.
A site uses this link format for everything:
example.com/?article=123
example.com/?category=456
example.com/?article=789&picture=012
An ASP classic default.asp catches all of this and does stuff with it.
I would really like to create a couple of routes for these old type of Url's with querystrings on the root, so I can catch them in a separate controller and do some tricks on them (permanent redirects).
When I try to create a route that contains a questionmark, I am told that is not possible.
This could be a good case for Global Action Filters if there's no way to handle these using routes (Although I imagine there is).
You could process the incoming url in the OnActionExecuting method and redirect as appropriate.
UPDATE
There's a good SO answer here on how to redirect as you require. It may not be exactly as you've asked however a similar principle should acheive what you're after quite easily.
Imagine a Web Forms application with routing.
A clean page name like:
http://www.mywebsite.com/home
Might have an underlying of URL of:
http://www.mywebsite.com/page.aspx?id=3
If a user enters http://www.mywebsiter.com/page.aspx?id=3 into a browser, I need to redirect to http://www.mywebsite.com/home
Is this possible to do?
I can't work out a way to do this as the routing engine is not executed for a physical page and in the page.aspx Page_Load method I have no way of knowing whether the URL was entered directly or was the result of a route.
You can use the Page.RouteData.Values collection to detect if the page is being loaded due to routing, rather than a direct URL. That can be done in Page_Load().
If there are route data values (you would likely check for values that you would know should exist), then they are fine. If there are no route data values, the page has loaded 'directly', and you should redirect them.
Check out the IIS URL rewrite module.
You could also look at things like disabling routing for files (RouteTable.Routes.RouteExistingFiles = false;) - that could be dangerous though!
I'm wondering if it is possibile to customize routing in a way that all requests are evaluated by a piece of code, redirected to the relevant controller if a match is found or passed to next rout in list if not found.
sample request:
/my coolpage/another one
the code searches and determine that the right controller for this is
Page, action is "list" and id is "123" and so redirects
another request:
/products/list/5
code finds no match al passes it back to next route that knows how to handle it...
any idea on how to do this?
Custom Route class
If you really need this kind of request mangling and you can't do it with IIS URL Rewriting module, then writing your own Route class is your best bet. You will probably have to write some other parts as well, but a custom Route class will be your starting point.