Данное руководство устарело. Актуальное руководство: Руководство по ASP.NET Core 7
Кроме хелперов форм и шаблонных хелперов в ASP.NET Core MVC также имеется ряд методов, которые применяются для генерации исходящих адресов в приложении, например, при выводе их в представлении.
Наиболее простой способ вывода адреса является использование анкора - элемента a
:
<a href="~/Home/Index/3" />
Но также мы можем использовать специальные хелперы рендеринга - Html.ActionLink и Html.RouteLink.
Хелпер ActionLink
создает гиперссылку на действие контроллера. Если мы создаем ссылку на действие, определенное в том же
контроллере, то можем просто указать имя действия:
@Html.ActionLink("О сайте", "About")
Что создаст вам следующую разметку:
<a href="/Home/About">О сайте</a>
Если необходимо указать ссылку на действие из другого контроллера, то в хелпере ActionLink
в качестве третьего аргумента
имя контроллера. Например, ссылка на действие List
контроллера Book
будет создаваться так:
@Html.ActionLink("Список книг", "List", "Book")
Кроме того, если у нас в некотором методе Index контроллера HomeController определено несколько параметров:
public class HomeController : Controller { public IActionResult GetUser(string name="Тоm", int id = 1) { return Content($"{id}. {name}"); } // остальные методы }
То перегруженная версия хелпера ActionLink
позволяет передать параметр объекта (обычно анонимный тип) для параметра routeValues
.
Среда выполнения принимает свойства объекта и использует их для создания значений маршрутизации (имена свойств становятся именами параметров маршрута, а значения свойств представляют значения параметра маршрута).
Создадим ссылку для вышеопределенного действия контроллера:
@Html.ActionLink("Пользователь 10", "GetUser", "Home", new { id = 10 }, null) @Html.ActionLink("Alice", "GetUser", "Home", new { name = "Alice", id = 5 }, null)
Последний параметр в данном хелпере является параметром htmlAttributes
. Мы можем использовать этот параметр для установки
значения атрибута элемента HTML. В данном случае передается значение null (то есть никаких атрибутов не устанавливается).
Теперь попробуем передать атрибуты, например, установить атрибуты id
и class
:
@Html.ActionLink("Sam", "GetUser", "Home", new { name = "Sam", id = 12 }, new { id = "sam", @class = "link" })
Сгенерированная html-разметка будет выглядеть следующим образом:
<a class="link" href="/Home/GetUser/12?name=Sam" id="sam">Sam</a>
Обратите внимание на знак @
перед словом class: поскольку слово "class" является зарезервированным словом в C#, то
для правильного рендеринга нам надо перед ним указать знак @.
Хелпер RouteLink
использует похожий шаблон, что и ActionLink
: он принимает имя маршрута, но не требует
аргументов для имени контроллера и имени действия. Так, последний пример с ActionLink
эквивалентен следующему коду:
@Html.RouteLink("Sam", new { controller = "Home", action = "GetUser", name = "Sam", id = 12 }, new { id = "sam", @class = "link" })
Чтобы использовать маршрут, нам просто надо указать имя определенного нами маршрута и затем определить при необходимости дополнительные параметры. Например, возьмем стандартный маршрут default, который определен в классе Startup:
app.UseEndpoints(endpoints => { endpoints.MapControllerRoute( name: "default", pattern: "{controller=Home}/{action=Index}/{id?}"); });
Тогда создать ссылку мы можем, например, так:
@Html.RouteLink("Все пользователи","Default",new { action = "UsersList" })
В данном случае используется шаблон марщрута с именем default - то есть трехсегментный шаблон, где последний сегмент не обязателен. Мы указали действие UsersList, но не указали контроллер, поэтому будет использоваться контроллер по умолчанию (если он указан в определении маршрута) - HomeController. В итоге сгенерированная ссылка будет выглядеть так:
<a href="/Home/UsersList">Все пользователи</a>
Собственно имена маршрутов и используются в основном для создания ссылок.
При генерации ссылок фрейворк MVC опирается на систему маршрутизации. Допустим, в классе Startup определено несколько маршрутов:
app.UseEndpoints(endpoints => { endpoints.MapControllerRoute( name: "products", pattern: "Products/{action}/{id?}", defaults: new { controller = "Home" }); endpoints.MapControllerRoute( name: "default", pattern: "{controller=Home}/{action=Index}/{id?}"); });
Первым здесь установлен маршрут "products", который будет сопоставлять запросы к контроллеру Home с маршрутом "Products/{action}/{id?}". В частности, запрос http://localhost:55994/Products/Index будет обрабатываться методом Index контроллера Home.
И теперь выражение
@Html.ActionLink("Жми здесь", "Index", "Home")
Сгенерирует следующую ссылку
<a href="/Products/Index">Жми здесь</a>
И не смотря на то, что у нас также определен стандартный маршрут, который позволяет генерировать стандартные ссылки, включающие имя контроллера и имя его метода, но в данном случае для генерации ссылок будет применяться первый маршрут, который маршрут который совпадает с определением ссылки.
Так, пусть у нас определены следующие маршруты:
app.UseEndpoints(endpoints => { endpoints.MapControllerRoute( name: "default", pattern: "BookStore", defaults: new { controller = "Book", action = "Index" }); endpoints.MapControllerRoute( name: "default1", pattern: "Store/Sub{action}/{id?}", defaults: new { controller = "Home" }); endpoints.MapControllerRoute( name: "default2", pattern: "{controller=Home}/{action=Index}/{id?}"); });
Из определения маршрутов ясно, то запрос http://localhost:55994/BookStore будет обрабатываться методом Index контроллера Book. А запрос http://localhost:55994/Store/SubIndex/ будет обрабатываться контроллером Home и его методом Index.
Теперь пусть у нас в представлении создаются две ссылки:
@Html.ActionLink("Home", "Index", "Home") @Html.ActionLink("Book", "Index", "Book")
Первая ссылка соответствует второму маршруту, так как для определения ссылки используется контроллер Home. Поэтому в соответствии со вторым маршрутом будет сгенерирована следующая ссылка:
http://localhost:55994/Store/SubIndex
Вторая же ссылка соответствует первому маршруту, который для обработки запроса применяет контроллер BookController. Поэтому второе выражение сгенерирует следующую ссылку:
http://localhost:55994/BookStore
Поэтому если в приложении определено несколько маршрутов, а в представлениях для генерации ссылок применяются хелперы типа Html.ActionLink, то следует проверять сгенерированные ссылки, иначе в результате можно получить совсем не то, что ожидалось.
Данные правила в отношении создания ссылок справедливы не только в отношении Html.ActionLink, но и в отношении хелпера Html.RouteUrl.
Например, вызов
@Html.RouteLink("Все книги", new { action = "Index", controller="Home" })
сгенерирует следующую ссылку:
<a href="/Store/SubIndex">Все книги</a>
Все, что было выше сказано в отношении маршрутов, применяется также в отношении атрибутов маршрутизации. Так, допустим, в контроллере HomeController используется атрибут Route:
public class HomeController : Controller { [Route("api/[controller]/[action]")] public IActionResult Index() { return View(); } // остальные методы }
В этом случае вызов
@Html.ActionLink("Home", "Index", "Home")
сгенерирует следующую ссылку:
http://localhost:55994/api/Home/Index