Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MVC4 routing @Html.ActionLink and @Html.RouteLink producing wrong urls

Maybe someone may help me to understand why @Html.ActionLink and @Html.RouteLink producing the wrong links in some cases.

I have routes declared like that:

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

            routes.MapRoute(
                "Catalog", // Route name
                "Catalog/{a}/{b}/{c}/{d}/{e}", // URL with parameters
                new { controller = "Catalog", action = "Index", a = UrlParameter.Optional, b = UrlParameter.Optional, c = UrlParameter.Optional, d = UrlParameter.Optional, e = UrlParameter.Optional } // Parameter defaults
            );

        routes.MapRoute(
            name: "Default",
            url: "{controller}/{action}/{id}",
            defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
        );
    }

I have controller with my params:

public ActionResult Index(string a, string b, string c, string d, string e)
        {
        //Do stuff;
        }

I have list of cases with @Html.RouteLink and @Html.ActionLink on the view declared like that:

    @Html.ActionLink("ActionLink1","Index", new { a = "a" }, null)
    @Html.ActionLink("ActionLink2","Index", new { a = "a", b = "b" }, null)
    @Html.ActionLink("ActionLink3","Index", new { a = "a", b = "b", c = "c" }, null)
    @Html.ActionLink("ActionLink4","Index", new { a = "a", b = "b", c = "c", d = "d" }, null)
    @Html.ActionLink("ActionLink5","Index", new { a = "a", b = "b", c = "c", d = "d", e = "e" }, null)
    <br/>
    @Html.RouteLink("RouteLink1","Catalog", new { a = "a" })
    @Html.RouteLink("RouteLink2","Catalog", new { a = "a", b = "b" })
    @Html.RouteLink("RouteLink3","Catalog", new { a = "a", b = "b", c = "c" })
    @Html.RouteLink("RouteLink4","Catalog", new { a = "a", b = "b", c = "c", d = "d" })
    @Html.RouteLink("RouteLink5","Catalog", new { a = "a", b = "b", c = "c", d = "d", e = "e" 
})

The Results

Current url http://localhost:2288/Catalog

ActionLink1

  • Actual Result: http://localhost:2288/Catalog?a=a
  • Expected Result: http://localhost:2288/Catalog/a

RouteLink1

  • Actual Result: http://localhost:2288/Catalog
  • Expected Results: http://localhost:2288/Catalog/a

Current url http://localhost:2288/Catalog/a

ActionLink1

  • Actual Result: http://localhost:2288/Catalog?a=a
  • Expected Results: http://localhost:2288/Catalog/a

Current url http://localhost:2288/Catalog/a/b

ActionLink1

  • Actual Result: http://localhost:2288/Catalog/a/b
  • Expected Results:http://localhost:2288/Catalog/a

RouteLink1

  • Actual Result: http://localhost:2288/Catalog/a/b
  • Expected Results: http://localhost:2288/Catalog/a

Current url http://localhost:2288/Catalog/a/b/c

ActionLink1

  • Actual Result: http://localhost:2288/Catalog/a/b/c
  • Expected Results: http://localhost:2288/Catalog/a

RouteLink1

  • Actual Result: http://localhost:2288/Catalog/a/b/c
  • Expected Results: http://localhost:2288/Catalog/a

ActionLink2

  • Actual Results: http://localhost:2288/Catalog/a/b/c
  • Expected Results: http://localhost:2288/Catalog/a/b

RouteLink2

  • Actual Results: http://localhost:2288/Catalog/a/b/c
  • Expected Results: http://localhost:2288/Catalog/a/b

And so on...


Current url http://localhost:2288/Catalog/a/b/c/d

ActionLink1, ActionLink2 and ActionLink3 as well as RouteLink1, RouteLink2, and RouteLink3 are all producing wrong urls.


Current url http://localhost:2288/Catalog/a/b/c/d/e

All ActionLinks and RouteLinks (exept ActionLink5 and RouteLinks5) are producing wrong urls.


I put a sample project here: http://www.mediafire.com/?gdbatoafgd0kf4w

May be someone can figure out why that is happening?

That story started some days ago when i was trying to build Breadcrumbs with MvcSiteMapProvider, and i got same links produced by MvcSiteMapProvider Breadcrumbs. During my research i figure out that MvcSiteMapProvider not causing the problem the problem somewhere else. So i created default MVC4 project and it has such strange behavior by default.

UPDATE

It is looks like when you are using @Html.ActionLink and @Html.RouteLink helpers url generated based on current url..but still can't understand why when Current url http://localhost:2288/Catalog I am getting:

http://localhost:2288/Catalog?a=a instead of http://localhost:2288/Catalog/a in case of ActionLink

and http://localhost:2288/Catalog instead of http://localhost:2288/Catalog/a in case of RouteLink

like image 252
Joper Avatar asked Apr 19 '13 03:04

Joper


1 Answers

The RouteLink allows you to explicitly specify a route name. The ActionLink evaluates the routes in the order they appeared in your route definitions. Your first route declaration is invalid and is the reason why the ActionLink helper is unable to capture it. The reason why your first route definition is invalid is because you made the {a}, {b}, {c} and {d} route parameters as UrlParameter.Optional but only the LAST parameter ({e} in your example) of an uri path can be optional.

Since RouteLink helper allows you to explicitly state which route you want to be picked up, you could use it as a workaround.

like image 116
Darin Dimitrov Avatar answered Oct 22 '22 14:10

Darin Dimitrov