Содержание
Как правило, компонент представления наследуется от 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 нет и, следовательно, его необходимо будет создать.
Второй момент — как производится поиск частичного представления. Опять же, по умолчанию, поиск необходимого частичного представления осуществляется по следующим путям:
- /Views/{Имя контроллера}/Components/{Имя компонента представления}/{Имя представления}
- /Views/Shared/Components/{Имя компонента представления}/{Имя представления}
- /Pages/Shared/Components/{Имя компонента представления}/{Имя представления}
- /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. Частичное представление компонента должно располагаться по одному из путей по умолчанию или же путь можно настроить, используя настройки сервисов в приложении.

