11

I have created a page route so I can integrate my MVC application with a few WebForms pages that exist in my project:

public static void RegisterRoutes(RouteCollection routes)
{
    routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

    // register the report routes
    routes.MapPageRoute("ReportTest",
        "reports/test",
        "~/WebForms/Test.aspx"
    );

    routes.MapRoute(
        "Default", // Route name
        "{controller}/{action}/{id}", // URL with parameters
        new { controller = "Home", action = "Index", id = UrlParameter.Optional } 
    );
}

This has created a problem whenever I use Html.ActionLink in my Views:

<%: Html.ActionLink("Home", "Index", "Home") %>

When I load the page in the browser the link appears like:

http://localhost:12345/reports/test?action=Index&controller=Home

Has anyone run into this before? How can I fix this?

Dismissile
  • 32,564
  • 38
  • 174
  • 263

2 Answers2

6

I just had a very similar issue. My solution was to give the routing system a reason to reject page route when looking for matches for the ActionLink.

Specifically, you can see in the generated URL that the ActionLink creates two parameters: controller and action. We can use those as a method to make our "standard" routes (~/controller/action/id) not match the page route.

By replacing the static "reports" in the page route with a parameter we'll call "controller" and then adding a constraint that the "controller" must be "reports" we get the same page route for our reports, but reject anything with a controller parameter that isn't "reports".

public static void RegisterRoutes(RouteCollection routes)
{
    routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

    // register the report routes
    // the second RouteValueDictionary sets the constraint that {controller} = "reports"
    routes.MapPageRoute("ReportTest",
        "{controller}/test",
        "~/WebForms/test.aspx",
        false,
        new RouteValueDictionary(),
        new RouteValueDictionary { { "controller", "reports"} });

    routes.MapRoute(
        "Default", // Route name
        "{controller}/{action}/{id}", // URL with parameters
        new { controller = "Home", action = "Index", id = UrlParameter.Optional } 
    );
}
nuanced
  • 71
  • 1
  • 6
6

My guess is that you need to add some parameter options to the MapPageRoute declaration. So if you have more than one webforms page in the WebForms directory this works well.

routes.MapPageRoute  ("ReportTest",
                      "reports/{pagename}",
                      "~/WebForms/{pagename}.aspx");

PS: You may also want to have a look at the RouteExistingFiles property of RouteCollection

An alternative would be to use

<%=Html.RouteLink("Home","Default", new {controller = "Home", action = "Index"})%>
Ahmad
  • 22,657
  • 9
  • 52
  • 84
  • 2
    Thanks. I wanted to avoid using RouteLink just for brevity but I might have to end up using it. I just don't understand why the page route is getting matched with my regular routes when I use ActionLink. – Dismissile Dec 15 '10 at 15:33