Как вы используете помощники тегов для создания ссылок на контроллеры / действия, которые используют косые черты в атрибутах маршрута?

Прежде чем я начну, я знаю, что есть похожие вопросы, но все они касаются использования слешей с параметрами в маршрутах, чего я не пытаюсь достичь (по крайней мере, пока).

Я создаю веб-приложение ASP.NET Core 2 MVC и испытываю проблемы с косыми чертами в моих маршрутах, которые экранируются при создании ссылок на мои действия. У меня есть следующий контроллер:

[Route("Manage/Account")]
public class AccountsController : Controller
{
    [Route("[Action]")]
    public IActionResult Index() => View();

    [Route("[Action]")]
    public IActionResult Other() => View();
}

И следующие ссылки в представлении:

<a asp-controller="Manage/Accounts" asp-action="Index">Accounts</a>
<a asp-controller="Manage/Account" asp-action="Other">Accounts (Other)</a>

Это создает следующий HTML:

<a href="/Manage%5CAccount">Accounts</a>
<a href="/Manage%5CAccount/Other">Accounts (Other)</a>

Обратите внимание, что косая черта была экранирована %5C что честно, работает и ссылки на самом деле приводят меня к правильным действиям. Кроме того, ручная установка обратной косой черты через адресную строку браузера также приводит меня к правильным действиям. Однако это дает мне несколько уродливых URL-адресов, которых я бы предпочел не иметь.

Кто-нибудь может предложить способ, чтобы помешать ему избежать моих ударов?

Изменить: Подробнее

В моих попытках довести мою проблему до минимума, я боюсь, что мог упустить какой-то важный контекст относительно моей конечной цели.

Я пытаюсь реализовать настройку папок функций, которую я успешно использовал с ASP.NET MVC5, которая использует маршрутизацию атрибутов и пользовательский механизм представления, чтобы разрешить вложенные функции. Чтобы сделать эту работу, я использовал [RoutePrefix(...)], Контроллер ниже будет в следующем каталоге ~/Features/Manage/Accounts:

[RoutePrefix("Manage/Accounts")]
public class Accounts : Controller
{
    [Route("Index")]
    public ActionResult Index() => View();

    [Route("Other")]
    public ActionResult Other() => View();
}

Затем ссылки были добавлены в такие представления:

@Html.ActionLink("Accounts", "Index", "Manage/Accounts")
@Html.ActionLink("Accounts (Other)", "Other", "Manage/Accounts")

Который затем отображается как:

<a href="/Manage/Accounts">Accounts</a>
<a href="/Manage/Accounts/Other">Accounts (Other)</a>

К сожалению [RoutePrefix(...)] атрибут недоступен в ASP.NET Core MVC, и может показаться, что при использовании стандартного [Route(...)] Атрибут не может эмулировать поведение, обнаруженное в MVC5.

2 ответа

Решение

Похоже, вы путаете контроллеры и маршруты. Когда используешь asp-controllerвы должны указать имя класса контроллера (без Controller суффикс). В вашем случае вам нужно:

<a asp-controller="Accounts" asp-action="Index">Accounts</a>
<a asp-controller="Accounts" asp-action="Other">Accounts (Other)</a>

Используя вышесказанное, вы должны получить ожидаемые маршруты:

<a href="/Manage/Account">Accounts</a>
<a href="/Manage/Account/Other">Accounts (Other)</a>

Кроме того, вы можете упростить ваши атрибуты, например, так:

[Route("Manage/Account/[action]")]
public class AccountsController : Controller
{
    public IActionResult Index() => View();

    public IActionResult Other() => View();
}

[action] Токен может быть применен на уровне контроллера, как показано, избегая необходимости добавлять его к каждому методу.

То, что сказал @Kirk, совершенно верно. Я просто хочу дать вам представление о Area в MVC также, потому что, глядя на ссылки в вашем примере, похоже, что вы хотите, чтобы эти ссылки начинались с /manage,

Ранее я рассказывал, как настроить области в MVC. Вы можете посмотреть здесь.