(Before starting: I am aware of this and this. I'd like to find a more concise solution -if possible- for a slightly more specific problem)
I'm rewriting an old Webforms app in MVC. As usual, no permalinks should be broken.
I'm using standard {controller}/{action}/{id}
routes. Legacy paths are usually SomePage.aspx?ID=xxx
, and I have one particular case where Foo.aspx
is a list of Bar
(new URL: /Bar or /Bar/Index) and
Foo.aspx?ID=xxx
is the Bar
detail (new URL: /Bar/View/xxx)
One possible workaround is adding the following before the Default MapRoute
:
routes.MapRoute("Bar View", "Foo.aspx",
new { controller = "Bar", action = "View" });
And then defining the corresponding action in BarController:
public ActionResult View(int? id)
{
if (id == null)
return RedirectToAction("Index");
return View();
}
There are two problems with this:
I'm fine with mapping the legacy URLs by hand (I don't need a generic solution and there are only about 8 pages)
This is a new project, so I'm not tied to anything.
I was able to solve this based on Dangerous' idea plus a constraint based on this answer.
My new route table is:
routes.MapRoute("Bar", "Bar/{action}/{id}",
new
{
controller = "Bar",
action = "Index",
id = UrlParameter.Optional
});
routes.MapRoute("Bar View", "Foo.aspx",
new {controller = "Bar", action = "View"},
new {id = new QueryStringConstraint()});
routes.MapRoute("Bar Index", "Foo.aspx",
new { controller = "Bar", action = "Index" });
routes.MapRoute("Default", /*...*/);
And the QueryStringConstraint couldn't be simpler:
public class QueryStringConstraint : IRouteConstraint
{
public bool Match(HttpContextBase httpContext, Route route,
string parameterName, RouteValueDictionary values,
RouteDirection routeDirection)
{
return httpContext.Request.QueryString.AllKeys
.Contains(parameterName, StringComparer.InvariantCultureIgnoreCase);
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With