Контроллеры ASP.NET Core MVC. Введение

Как мы уже знаем, контроллер занимается в MVC центральную роль в приложении — этот тот компонент, который обрабатывает запрос пользователя и отвечает за какие-либо действия. Здесь и далее в этой части мы будем изучать работу с контроллерами в ASP.NET Core MVC.

Вернемся к нашему первому приложению ASP.NET Core MVC и более детально рассмотрим класс контроллера HomeController.

Что является контроллером в ASP.NET Core MVC

Посмотрим на контроллер в нашем первом приложении ASP.NET Core MVC и разберемся, что отличает контроллер от любого другого класса C#. Вот его код

public class HomeController : Controller
{
    private readonly ILogger<HomeController> _logger;

    public HomeController(ILogger<HomeController> logger)
    {
        _logger = logger;
    }

    public IActionResult Index()
    {
        return View();
    }

    public IActionResult Privacy()
    {
        return View();
    }

    [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
    public IActionResult Error()
    {
        return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });
    }
}

Первое, на что необходимо обратить внимание — это на то, что класс, который в нашем приложении является контроллером наследуется от класса Controller. По соглашению, контроллером считаются следующие классы

  1. имя класса контроллера содержит суффикс Controller,
  2. класс наследуется от класса Controller
  3. для класса указан атрибут [Controller]

В нашем случае, использован второй вариант определения контроллера в приложении — наследование от класса Controller, так как такой подход имеет ряд преимуществ, в том числе, доступ к контексту запроса и возможность использования вспомогательных методов отправки ответов клиенту.

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

public class Home : Controller

при этом, ничего не изменится, класс всё также будет считаться контроллером с именем Home. Если же мы будем использовать атрибут, например, так:

[Controller]
public class Home

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

Следующий момент, на который обратим внимание — это конструктор класса:

public HomeController(ILogger<HomeController> logger)
 {
     _logger = logger;
 }

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

Действия контроллера

Все публичные методы класса контроллера по умолчанию считаются его действиями. И, хотя, как и любой другой метод C# действие контроллера может возвращать любой тип данных, например, строки или числа, обычно результатом действия контроллера является какой-либо объект, реализующий интерфейс IActionResult. Например, в нашем классе контроллера определено действие:

public IActionResult Index()
{
    return View();
}

Это действие возвращает объект типа ViewResult, который является наследником абстрактного класса ActionResult, реализующего интерфейс IActionResult.

Действия контроллера обычно сопоставляются с маршрутом запроса. Если же мы хотим сделать так, чтобы публичный метод не был действием контроллера, то для такого метода применяется атрибут [NoAction]. Например, применим этот атрибут для метода Index() и посмотрим на результат

[NonAction]
public IActionResult Index()
{
    return View();
}

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

Обращение к действиям контроллера

Чтобы мы могли обращаться к действиям контроллера, в ASP.NET Core используется система маршрутизации. Конкретно для ASP.NET Core MVC общепринятым считается использование трехсегментной структуры запроса. Например, как в нашем приложении:

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

о методе MapControllerRoute()  мы говорили в предыдущей части. Такую систему удобно использовать для однозначной понятной системы обращения пользователей к ресурсам приложения. Например:

  • localhost:7212/Home/Index — вернуть нам главную страницу приложения
  • localhost:7212/Tasks/Add — добавить новую задачу в список
  • localhost:7212/Tasks/Delete/5 — удалить задачу с Id = 5
  • и т.д.

хотя, при желании мы можем использовать и двух- и четырех- сегментные схемы, но предложенная изначально трехсегментная система, на мой скромный взгляд, является наиболее удобной в использовании и логичной, в принципе, для ASP.NET Core MVC. Что ж, со структурой и особенностями контроллера разобрались. Теперь попробуем написать свой контроллер.

Первый контроллер в ASP.NET Core MVC

Создадим новое приложение ASP.NET Core MVC, как мы это делали в предыдущей части. Добавим в папку Controllers новый контроллер. Для этого, мы можем выбрать в контекстном мен. пункт «Контроллер»

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

Для примера был выбран шаблон пустого контролера. Название контроллера — SimpleController. В итоге мы должны увидеть следующий код:

using Microsoft.AspNetCore.Mvc;

namespace FirstMvcSite.Controllers
{
    public class SimpleController1 : Controller
    {
        public IActionResult Index()
        {
            return View();
        }
    }
}

здесь уже определено одно действие Index, но нам оно сегодня не понадобится, поэтому можем его смело удалить и напишем следующий метод:

//действие контроллера
public string Hello()
{
    return "Hello Controller";
}

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

немного усложним задачу и задействуем в работе контроллера третий сегмент пути (id):

public class SimpleController : Controller
{
    //действие контроллера
    public string Hello(string? id)
    {
        if (string.IsNullOrWhiteSpace(id))
            return "Hello Controller";
        else
            return $"Hello {id}";
    }
}

снова вернемся к шаблону маршрута и разберемся с тем, что теперь будет происходить в действии контроллера. Шаблон маршрута:

{controller=Home}/{action=Index}/{id?}

с первыми двумя параметрами все должно быть понятно — это имя контроллера и его действие. Третий параметр — необязательный, на что указывает знак вопроса после имени параметра. Следовательно и в методе действия контроллера мы определяем тип параметра допускающего null и имя параметра метода соответствует имени параметра в шаблоне маршрута. Если третий параметр не будет задан или вместо него будет пробел, то вернется строка «Hello Controller», иначе, после Hello будет подставлено значение параметра. Например:

Итого

Контроллер в ASP.NET Core — это, обычно, публичный класс, соответствующий хотя бы одному из трех условий: унаследован от класса Controller, содержит в названии суффикс Controller, для класса определен атрибут [Controller]. Публичные методы класса контроллера не помеченные атрибутом [NoAction] являются действиями контроллера, которые могут сопоставляться системой маршрутизации с шаблонами маршрутов. Действие контроллера может возвращать любые типы данных, но предпочтительным вариантом является возврат одного из объектов, реализующих интерфейса IActionResult.

Подписаться
Уведомить о
guest
0 Комментарий
Старые
Новые Популярные
Межтекстовые Отзывы
Посмотреть все комментарии