Before I start, I am aware there are similar questions to this, but they all pertain to using slashes with parameters in the routes which is not what I am trying to achieve (at least not yet).
I am creating an ASP.NET Core 2 MVC web application and am having problems with slashes in my routes being escaped when creating links to my actions. I have the following controller:
[Route("Manage/Account")]
public class AccountsController : Controller
{
[Route("[Action]")]
public IActionResult Index() => View();
[Route("[Action]")]
public IActionResult Other() => View();
}
And the following links in a view:
<a asp-controller="Manage/Accounts" asp-action="Index">Accounts</a>
<a asp-controller="Manage/Account" asp-action="Other">Accounts (Other)</a>
This generates the following HTML:
<a href="/Manage%5CAccount">Accounts</a>
<a href="/Manage%5CAccount/Other">Accounts (Other)</a>
Notice that the slash has been escaped to %5C
which to be fair does work and the links actually take me to the correct actions. Additionally manually putting the slash back in via the browsers address bar also takes me to the correct action. However this does give me some ugly URLs that I would rather not have.
Can anyone suggest a way to stop it from escaping my slashes?
Edit: More details
In my efforts to distil my problem down to the bare minimum I fear I may have left out some important context regarding my ultimate goal.
I am trying to implement a a feature folders setup that I have successfully used with ASP.NET MVC5 that makes use of attribute routing and a custom view engine to allow nested features. To make this work I used the [RoutePrefix(...)]
. The controller below would be in the following directory ~/Features/Manage/Accounts
:
[RoutePrefix("Manage/Accounts")]
public class Accounts : Controller
{
[Route("Index")]
public ActionResult Index() => View();
[Route("Other")]
public ActionResult Other() => View();
}
Links were then added in views like this:
@Html.ActionLink("Accounts", "Index", "Manage/Accounts")
@Html.ActionLink("Accounts (Other)", "Other", "Manage/Accounts")
Which then renders as:
<a href="/Manage/Accounts">Accounts</a>
<a href="/Manage/Accounts/Other">Accounts (Other)</a>
Sadly the [RoutePrefix(...)]
attribute is not available in ASP.NET Core MVC, and it would appear that using the standard [Route(...)]
attribute is not able to emulate the behaviour found in MVC5.
It appears that you're confusing controllers and routes. When using asp-controller
, you're expected to provide the name of a controller class (without the Controller
suffix). In your case, you need:
<a asp-controller="Accounts" asp-action="Index">Accounts</a>
<a asp-controller="Accounts" asp-action="Other">Accounts (Other)</a>
Using the above, you should end up with the expected routes:
<a href="/Manage/Account">Accounts</a>
<a href="/Manage/Account/Other">Accounts (Other)</a>
As an aside, you can simplify your attributes, like so:
[Route("Manage/Account/[action]")]
public class AccountsController : Controller
{
public IActionResult Index() => View();
public IActionResult Other() => View();
}
The [action]
token can be applied at the controller level, as shown, avoiding the need to add it to each method.