AnchorTagHelper

Данное руководство устарело. Актуальное руководство: Руководство по ASP.NET Core 7

Последнее обновление: 05.12.2019

AnchorTagHelper представляет тег-хелпер, который позволяет создавать ссылки. Он может принимать ряд специальных атрибутов:

  • asp-controller: указывает на контроллер, которому предназначен запрос

  • asp-action: указывает на действие контроллера

  • asp-area: указывает на действие область, в которой расположен контроллер или страница RazorPage (если они находятся в отдельной области)

  • asp-page: указывает на RazorPage, которая будет обрабатывать запрос

  • asp-page-handler: указывает на обработчик страницы RazorPage, которая будет применяться для обработки запроса

  • asp-host: указывает на домен сайта

  • asp-protocol: определяет протокол (http или https)

  • asp-route: указывает на название маршрута

  • asp-all-route-data: устанавливает набор значений для параметров

  • asp-route-[название параметра]: определяет значение для определенного параметра

  • asp-fragment: определяет ту часть хэш-ссылки, которая идет после символа решетки #. Например, "paragraph2" в ссылке "http://mysite.com/#paragraph2"

asp-action и asp-controller

Мы можем создавать ссылки в ASP.NET Core различными способами. Например:

@Html.ActionLink("О сайте","About","Home")
<a href='@Url.Action("About", "Home")'>О сайте</a>

В первом случае используется html-хелпер, во втором - стандартный элемент ссылки с хелпером Url.Content. Еще один способ предоставляют tag-хелпер AnchorTagHelper:

<a asp-controller="Home" asp-action="About">О сайте</a>

В данном случае используется не элемент html <a />, а именно хелпер AnchorTagHelper. Его атрибут asp-controller указывает на название контроллера, а asp-action определяет действие, которому будет идти запрос. Если указан атрибут asp-action, но не указан asp-controller, то в качестве контроллера используется тот контроллер, который связан с текущим представлением.

Если необходимо установить ссылку на действие контроллера, который находится в другой области, то применяется атрибут asp-area:

<a asp-controller="Home" asp-action="About" asp-route-area="Service">О сайте</a>

В данном случае предполагается, что контроллер Home находится в области Service.

Если, наоборот, в представлении, которое находится в какой-нибудь области, надо создать ссылку на действие контроллера, который не находится ни в какой области, то указывается пустой атрибут:

<a asp-controller="Home" asp-action="About" asp-route-area="">О сайте</a>

asp-host и asp-protocol

AnchorTagHelper по умолчанию создает локальную ссылку, если же нам надо создать ссылку на другой домен, то мы можем применить атрибут asp-host:

<a asp-controller="Home" asp-action="About" asp-host="localhost.com" asp-protocol="https">О сайте</a>

Кроме того, мы можем изменить стандартный протокол на https, использовав атрибут asp-protocol. Данный элемент в итоге создает следующую ссылку: https://localhost.com/Home/About

asp-route- и asp-all-route-data

А что если у нас метод принимает какие-нибудь параметры, которые надо указать в ссылке:

public IActionResult GetPerson(int id){......}

В этом случае мы можем использовать атрибут asp-route-:

<a asp-controller="Home" asp-action="GetPerson" asp-route-id="5" >Item5</a>

Если метод принимает несколько параметров, например:

public IActionResult GetPerson(int id, string name, int age)
{
	return Content($"id={id}  name={name}  age={age}");
}

то мы можем указать несколько атрибутов asp-route-:

<a asp-controller="Home" asp-action="GetPerson" asp-route-id="5"  asp-route-age="18" asp-route-name="tom" >Item5</a>

Чтобы не устанавливать все параметры по отдельности, можно применить атрибут asp-all-route-data:

<a asp-controller="Home" asp-action="GetPerson" asp-all-route-data='new Dictionary<string,string> { { "id", "5" }, {"name", "tom" }, { "age", "18" } }' >Item5</a>

asp-all-route-data в качестве значения принимает словарь с параметрами и их значениями. В результате будет генерироваться ссылка, аналогичная предыдущей.

Влияние системы маршрутизации

При использовавании данного тег-хелпера может возникнуть вопрос, а какая именно ссылка будет сгенерирована? В реальности ответ на этот вопрос зависиот системы маршрутизации. Например, по умолчанию в проекте определен один маршрут (в методе Configure класса Startup):

endpoints.MapControllerRoute(
	name: "default",
	pattern: "{controller=Home}/{action=Index}/{id?}");

Возьмем предпоследний пример:

<a asp-controller="Home" asp-action="GetPerson" asp-route-id="5"  asp-route-age="18" asp-route-name="tom" >Item5</a>

В итоге будет создаваться следующая ссылка: http://localhost:1234/Home/GetPerson/5?name=tom&age=18. Обратите внимание, что параметр id является частью шаблона маршрута, поэтому в сгенерированной ссылке он не входит строку запроса.

Если мы немного изменим определение маршрута, убрав сегмент параметра id:

endpoints.MapControllerRoute(
	name: "default",
	pattern: "{controller=Home}/{action=Index}");

То параметр id будет трактоваться как часть строки запроса: http://localhost:60141/Home/GetPerson?id=5&name=tom&age=18

Но это только одна из частностей. Возьмем другой пример. Допустим, в классе 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:xxxxx/Products/Index будет обрабатываться методом Index контроллера Home.

И теперь следующий тег

<a asp-controller="Home" asp-action="Index">Жми здесь</a>

сгенерирует следующую ссылку

<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:xxxxx/BookStore будет обрабатываться методом Index контроллера Book. А запрос http://localhost:xxxxx/Store/SubIndex/ будет обрабатываться контроллером Home и его методом Index.

Теперь пусть у нас в представлении создаются две ссылки:

<p>
    <a asp-controller="Home" asp-action="Index">Home</a>
</p>
<p>
    <a asp-controller="Book" asp-action="Index">Book</a>
</p>

Первая ссылка соответствует второму маршруту, так как для определения ссылки используется контроллер Home. Поэтому в соответствии со вторым маршрутом будет сгенерирована следующая ссылка:

http://localhost:xxxxx/Store/SubIndex

Вторая же ссылка соответствует первому маршруту, который для обработки запроса применяет контроллер BookController. Поэтому второе выражение сгенерирует следующую ссылку:

http://localhost:xxxxx/BookStore

Поэтому если в приложении определено несколько маршрутов, то следует учитывать систему маршрутизации и проверять сгенерированные ссылки, иначе в результате можно получить совсем не то, что ожидалось.

asp-route

С помощью параметра asp-route можно сгенерировать ссылку на основании маршрута. Например, пусть у нас есть такой маршрут:

app.UseEndpoints(endpoints =>
{
	endpoints.MapControllerRoute(
		name: "book",
		pattern: "BookStore",
		defaults: new { controller = "Book", action = "Index" });

	endpoints.MapControllerRoute(
		name: "default",
		pattern: "{controller=Home}/{action=Index}/{id?}");
});

Возьмем первый маршрут по имени "book":

<a asp-route="book">Книги</a>

Такой тег создаст следующую ссылку:

<a href="/BookStore">Книги</a>
Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850