Компоненты представлений в ASP.NET Core MVC. ViewComponentResult и работа с представлениями

Как правило, компонент представления наследуется от ViewComponent, инициализирует модель и передает ее в представление, вызвав один из перегруженных методов View() класса ViewComponent. Именно эти методы генерирует объект ViewComponentResult.

Метод View() класса ViewComponent

В базовом классе компонента представлений ViewComponent опрелены следующие перегруженные версии метода View():

View() Возвращает результат, который будет отображать частичное представление с именем Default.
View(string? viewName) Возвращает результат, который будет отображать частичное представление с именем viewName.
View<TModel>(TModel? model) Возвращает результат, который будет отображать частичное представление с именем Default. При этом, в представление передается модель model
View<TModel>(string? viewName, TModel? model) Возвращает результат, который будет отображать частичное представление с именем viewName. При этом, в представление передается модель model

Первое, на что необходимо обратить внимание — это то, что, если в метод View() не передается имя представления, то ASP.NET Core MVC использует некое частичное представление по умолчанию с именем Default. Как мы знаем, такого представления по умолчанию в пустом проекте ASP.NET Core MVC нет и, следовательно, его необходимо будет создать.

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

  1. /Views/{Имя контроллера}/Components/{Имя компонента представления}/{Имя представления}
  2. /Views/Shared/Components/{Имя компонента представления}/{Имя представления}
  3. /Pages/Shared/Components/{Имя компонента представления}/{Имя представления}
  4. /Area/{Имя области}/Views/Shared/Components/{View Component Name}/{View Component Name}/{View Name}

Сами разработчики Microsoft дают следующую рекомендацию по размещению частичного представления Default.cshtml: использовать путь Views/Shared/Components/{View Component Name}/{View Name}.

Например, если наш компонент называется DayInfo, то рекомендуемый путь будет таким: Views/Shared/Components/DayInfo/Default.cshtml

С теорией немного разобрались, теперь перейдем к практике.

Использование метода View()

В качестве примера, разработаем небольшой компонент, представляющий меню навигации. Создадим новый пустой проект ASP.NET Core MVC, добавим в него папку Components и в этой папке создадим файл с именем Menu.cs:

Содержимое файла будет следующим:

using Microsoft.AspNetCore.Mvc;

namespace AspMvcComponents.Components
{
    public class MenuItem
    {
        public string Name { get; set; }
        public string Link { get; set; }
    }

    public class Menu: ViewComponent
    {
        public IViewComponentResult Invoke(List<MenuItem> items)
        {
            return View(items);
        }
    }
}

Всё, что делает наш компонент — это принимает список компонентов меню и передает их в представление, используя для этого метод View(). При этом, использоваться будет частичное представление с именем Default.cshtml. Теперь создадим частичное представление Default.cshtml. Расположим этот файл в папке Views/Shared/Components/Menu/Default.cshtml:

Содержимое представления:

@using AspMvcComponents.Components
@model IEnumerable<MenuItem> 

<ul>
    @foreach (var item in Model)
    {
        <li><a href="@item.Link">@item.Name</a></li>
    }
</ul>

В представлении используется модель нашего меню, а данные мы получим из компонента. Теперь зарегистрируем наш компонент в качестве tag-хэлпера и разместим его в любом другом представлении (или в нескольких, если потребуется). Например, воспользуемся представлением Index.cshtml:

@addTagHelper *, AspMvcComponents
@using AspMvcComponents.Components

@{
    ViewData["Title"] = "Home Page";
}

<vc:menu items="@(new() 
  { new MenuItem() { Name="Главная", Link = "/"},
    new MenuItem() { Name="Privacy", Link = "/home/privacy"}
})">
</vc:menu>

В качестве параметров, мы передали в компонент список пунктов меню. Теперь запустим приложение и получим следующий результат:

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

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

public IViewComponentResult Invoke(List<MenuItem> items)
{
    return View("menu", items);
}

здесь «menu» — это имя частичного представления для компонента.

Настройка пути поиска представления

Иногда бывает не совсем удобно держать код компонента в одной папке, а частичное представление для этого компонента — в другой. ASP.NET Core MVC позволяет настраивать пути поиска частичных представлений компонентов. Например, настроим путь поиска таким образом, чтобы частичное представление находилось в той же папке, что и код компонента. Для этого перейдем в файл Program.cs и добавим настройки для сервиса:

builder.Services.AddControllersWithViews().AddRazorOptions(options => 
{
    options.ViewLocationFormats.Add("/{0}.cshtml");
});

Здесь заполнитель {0} будет соответствовать пути Components/{View Component Name}/{View Name}. Чтобы использовать этот путь поиска, изменим немного структуру нашего проекта, а именно — создадим для нашего компонента и его представления отдельную папку в папке Components. Должна получиться вот такая структура проекта:

Теперь можно снова запустить проект и убедиться, что частичное представление берется по пути /Components/Menu/Default.cshtml:

Итого

Компоненты представлений могут передавать данные в частичные представления, используя методы View() родительского компонента ViewComponent. Частичное представление компонента должно располагаться по одному из путей по умолчанию или же путь можно настроить, используя настройки сервисов в приложении.

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