Маршруты и генерация ссылок

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

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

При генерации ссылок фрейворк MVC опирается на систему маршрутизации. Допустим, в классе Startup определено несколько маршрутов:

using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;

namespace MvcRoutingApp
{
    public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        public void ConfigureServices(IServiceCollection services)
        {
            services.AddControllersWithViews();
        }

        public void Configure(IApplicationBuilder app)
        {
            app.UseDeveloperExceptionPage();
            app.UseStaticFiles();

            app.UseRouting();
            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")

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

http://localhost:55994/Products/Index

И не смотря на то, что у нас также определен стандартный маршрут, который позволяет генерировать стандартные ссылки, включающие имя контроллера и имя его метода, но в данном случае для генерации ссылок будет применяться первый маршрут, который маршрут который совпадает с определением ссылки.

Так, пусть у нас определены следующие маршруты:

app.UseMvc(routes =>
{
    routes.MapRoute(
        name: "default",
        template: "BookStore",
        defaults: new { controller = "Book", action="Index" });
    routes.MapRoute(
        name: "default1",
        template: "Store/Sub{action}/{id?}",
        defaults: new { controller = "Home" });
    routes.MapRoute(
        name: "default2",
        template: "{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, а также tag-хелпера AnchorTagHelper.

Например, вызов

@Html.RouteLink("Все книги", new { action = "Index", controller="Home" })

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

<a href="/Store/SubIndex">Все книги</a>

А tag-хелпер

<a asp-action="Index" asp-controller="Book">Книги</a>

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

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