Handling legacy url's for any level in MVC
I have upgraded an old php site to asp.net MVC and I want to handle all the legacy URL's. I don't need them to map to the current pages as the content is all new but I do want to catch all requests for .php page and send them to the homepage (ideally with a permanent redirect for the search engines).
This works but only at the root level:
routes.MapRoute(
"LegacySite", // Route name
"{OldPage}.php", // URL with parameters
new { controller = "开发者_如何学GoHome", action = "index" }, // Parameter defaults
new string[] { "EatIn.Website.Controllers" }
);
I want to get all .php pages regardless of the folder they were in.
William,
I've got a similar scenario in an old mvc 1 website. However, the logic may still fit. I had a number of known pages and a variety of unknown pages to deal with. at the time, I dealt with it in the action using a rather cludgy approach as detailed below:
public ActionResult Index()
{
string routeval = (string)this.RouteData.Values["file"];
var dicT = new Dictionary<string, int>();
// oh deary me - hardcoded values
dicT.Add("algarve", 1);
dicT.Add("brazil", 5);
dicT.Add("colorado", 4);
dicT.Add("morocco", 2);
dicT.Add("thailand", 6);
// what, no test for culture/case :-)
if (dicT.ContainsKey(routeval))
{
var routeData = new RouteValueDictionary(
new
{
controller = "Property",
action = "Details",
id = dicT[routeval],
Lang = "en"
});
return RedirectToAction("Details", "Property", routeData);
}
else
{
return View();
}
}
[edit] - found another 'useful' bit of info on this from that old mvc1 app. you can add the following to your base controller:
public class LegacyUrlRoute : RouteBase
{
// source: http://www.mikesdotnetting.com/Article/108/Handling-Legacy-URLs-with-ASP.NET-MVC
public override RouteData GetRouteData(HttpContextBase httpContext)
{
const string status = "301 Moved Permanently";
var request = httpContext.Request;
var response = httpContext.Response;
var legacyUrl = request.Url.ToString();
var newUrl = "";
if (legacyUrl.Contains("/villas/") || legacyUrl.EndsWith("asp"))
{
if (legacyUrl.Contains("/villas/"))
newUrl = "/en/home/Destinations";
else if (legacyUrl.EndsWith("asp"))
{
newUrl = "/en/home/index";
if (legacyUrl.Contains("about"))
newUrl = "/en/home/AboutUs";
if (legacyUrl.Contains("offers"))
newUrl = "/en/home/Offers";
if (legacyUrl.Contains("contact"))
newUrl = "/en/home/ContactUs";
if (legacyUrl.Contains("destinations"))
newUrl = "/en/home/destinations";
if (legacyUrl.Contains("faq"))
newUrl = "/en/home/Faq";
if (legacyUrl.Contains("terms"))
newUrl = "/en/home/Terms";
if (legacyUrl.Contains("privacy"))
newUrl = "/en/home/Privacy";
}
response.Status = status;
response.RedirectLocation = newUrl;
response.End();
}
return null;
}
public override VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary values)
{
return null;
}
}
and then put a new route in your global.asax file:
routes.Add(new LegacyUrlRoute());
basically, i 'knew' that i was looking for a route value that contained a parameter of 'file' along the lines of www.url.com/somepage.asp?file=algarve
etc.. (this was how the old asp classic site worked and i knew that the present one didn't have this). For the 'known' routes that i wanted to redirect to, i used the logic that did the RedirectToAction
, everything else just went via the default Index() View()
.
As i said, cludgy and not neccesarily how i'd do it now (some 2.5 years later) but it was an example that i had 'floating around' and it actually works!! :D
good luck
Take a look at RouteMagic by Phil Haack - maybe it will help you.
Here's a blog entry that describes route redirection: http://haacked.com/archive/2011/02/02/redirecting-routes-to-maintain-persistent-urls.aspx
精彩评论