2.3. Маршрутизация на основе атрибутов

В прошлый раз мы познакомились с маршрутизацией в .NET 2.2. Маршрутизация в .NET Core MVCи тогда мы говорили о том, как все работает из коробки. Сегодня мы будем говорить о том, как можно с помощью атрибутов более гибко настраивать URL к определенному коду.

Давайте создадим новый контроллер. Откройте проект из Кликаем правой кнопкой по папке Controllers и выбираем создание нового файла. В появившемся окне MVC Controller Class или можно даже любой другой тип .cs файла, ведь главное это расширение и имя, а имя для нашего теста будет TestController.

Начнем с простого варианта:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;

namespace MyWebSite
{
  public class TestController : Controller
  {
    public string Index()
    {
       return "Test Index method";
    }
  }
}

Пока ничего нового – просто класс TestController, который происходит от базового контроллера Controller. Здесь метод по умолчанию Index. С маршрутизацией по умолчанию, которую мы рассматривали в предыдущей части, обращение к этому методу через браузер может быть через URL: /test/index. А что, если мы хотим сделать так, чтобы URL выглядел как /my/test/index?

Проблему можно решить двумя способами – первый (старый) добавить еще один маршрут. Открываем файл Startup.cs, находим вызов метода UseMvc в Configure и добавляем туда еще один маршрут:

app.UseMvc(routes =>
{
  routes.MapRoute(
    name: "my",
    template: "my/{controller=Home}/{action=Index}/{id?}"
  );
  routes.MapRoute(
    name: "default",
    template: "{controller=Home}/{action=Index}/{id?}"
  );
});

Теперь я дважды вызываю MapRoute. Первый параметр Name должен быть уникальным и просто отображать маршрут. Сначала желательно вызывать как можно более ограниченный маршрут, а потом уже более общий. По умолчанию относится как раз к общим. Наш новый более ограниченный, потому что должен работать только тогда, когда URL начинается с my/.

Запускаем приложение и можно убедиться, что все работает и теперь при обращении к /home/index и /my/test/index мы можем увидеть два уникальных страницы. Но это старый, не очень удобный подход, который я предпочитаю не использовать. Более удобный вариант – атрибуты. Перед именем класса и метода можно написать атрибут Route и в нем перезаписать часть URL.

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

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;

namespace MyWebSite
{
  [Route("my/test")]
  public class TestController : Controller
  {
    [Route("show")]
    public string Index()
    {
      return "Index Test method";
    }

    [Route("details/{id}")]
    public string Details(string id)
    {
      return "ID Value = " + id;
    }
  }
}

Перед строкой объявления класса я указываю, что все методы класса будут вызываться только тогда, когда URL начинается с my/test. В случае с классом в аттрибуте можно использовать Route или раньше еще поддерживался RoutePrefix, который похоже уже выпилили.

...
namespace MyWebSite
{
  [Route("my/test")]
  public class TestController : Controller
  {
    [Route("show")]
    public string Index()
    {
      return "Index Test method";
    }
    ...
    ...
  }
}

Теперь перед методами нужно указать оставшуюся часть URL. Для метода Index я указал show, а значит если загрузить URL /my/test/show, то будет вызван метод Index класса TestController.

Для метода Details указано details/{id}. Здесь фигурные скобки вокруг id не случайны. Этим мы указываем, что значение в этом месте будет передано самому методу в качестве параметра id.

Итак, если обратиться по адресу: /my/test/details/4, то будет вызван метод Details класса TestController, а число 4 как раз находится там, где у нас шаблон {id}, а значит это число передадут в качестве параметра id.

Скачать исходник

Предыдущая глава

2.2. Маршрутизация в .NET Core MVC

Следующая глава

2.4. Немного о контроллерах

О блоге

Программист, автор нескольких книг серии глазами хакера и просто блогер. Интересуюсь безопасностью, хотя хакером себя не считаю

Обратная связь

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

Пишите мне