Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MVC 6 Anchor Tag Helper not producing the expected href

Fairly straightforward issue.

<a asp-controller="Guide" asp-action="Index" asp-route-title="@Model.Title">Read more</a>

produces the link /Guide?title=Guide_no_1 but it is supposed to produce the link /Guide/Guide_no_1/

The documentation i can find all specify that its supposed to output /Guide/Guide_no_1/ so I have the feeling there is something i missed, a setting or some attribute somewhere.

the routes i have are like this, just incase they have an impact on link creation

[Route("/Guide/")]
public IActionResult Index() { ... }

[Route("/Guide/{title}/{page?}/")]
public IActionResult Index(string title, int page = 0) { ... }

[Route("/Guide/OnePage/{title}/")]
public IActionResult Index(string title) { ... }
like image 323
Thomas Andreè Wang Avatar asked May 09 '16 13:05

Thomas Andreè Wang


1 Answers

You need to specify the ordering of your attribute routes.

  • Otherwise they will be evaluated in the default order, which is probably based on reflection. The first one evaluated is the route /Guide/ which matches your specified controller and action, and since it is a match, no further routes are examined.

You need to order your routes so you evaluate first the most specific routes. In the case of attribute routing, you will do that using the Order parameter:

[Route("Guide/OnePage/{title}/", Order = 1)]
public IActionResult Index(string title) { ... }    

[Route("Guide/{title}/{page?}/", Order = 2)]
public IActionResult Index(string title, int page = 0) { ... }

[Route("Guide/", Order = 3)]
public IActionResult Index() { ... }
  • Please note the order in which they appear in the file doesn't matter, the evaluation order is based just in the Order parameter of the attribute. I just wrote them so the order of evaluation is clear.

Now you will notice that you also have a problem with the 2 routes with parameters Guide/OnePage/{title}/ and Guide/{title}/{page?}/. Since they have the same controller, action and required parameters, there is no way MVC can differentiate them and the one ordered first will always win!

  • Either use a different action name for one of those routes
  • Or assign a specific route name to the one that will always lose, so you can create links using that name:

    [Route("Guide/{title}/{page?}/", Name = "titleAndPage", Order = 2)]
    public IActionResult Index(string title, int page = 0) { ... }
    
    <a asp-route="titleAndPage" asp-route-title="fooTitle">Read more</a>
    
like image 168
Daniel J.G. Avatar answered Nov 08 '22 19:11

Daniel J.G.