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

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

Свойства ViewComponent

Класс ViewComponent предоставляет нам следующие полезные свойства, которые мы можем использовать в компоненте представления:

HttpContext представляет контекст HTTP, с помощью которого можно получить доступ к данным запроса пользователя и ответа. Подробнее работу с объектом этого класса мы рассматривали при изучении «чистого» ASP.NET Core.
ModelState представляет состояние модели в виде объекта ModelStateDictionary. Подробнее об объекте этого класса см. здесь
Request представляет контекст запроса в виде объекта HttpRequest. Подробнее об объекте этого класса см. здесь.
RouteData возвращает данные текущего маршрута
Url представляет объект класса, реализующего интерфейс IUrlHelper, который используется для генерации адресов URL
User представляет объект класса, реализующего интерфейс IPrincipal (данные пользователя). Может использоваться для авторизации пользователей
UserClaimsPrincipal представляет объект класса ClaimsPrincipal для текущего пользователя.
ViewBag представляет динамический объект, который может использоваться для передачи данных в представление. Подробнее об этом объекте см. здесь
ViewContext описывает контекст представления, в котором вызывается компонент
ViewComponentContext представляет объект ViewComponentContext, который инкапсулирует контекст компонента
ViewData возвращает объект ViewDataDictionary, который может применяться для передачи данных в представление. Подробнее об этом объекте см. здесь

Продемонстрируем работу со свойствами ViewComponent на примере информации о запросе пользователя (свойство Request). В предыдущей части мы разработали компонент меню:

сам компонент (файл Menu.cs)

using Microsoft.AspNetCore.Mvc;

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

    public class Menu : ViewComponent
    {
        public IViewComponentResult Invoke(List<MenuItem> items)
        {
            if (Request.Query.ContainsKey("exclude") && Convert.ToBoolean(Request.Query["exclude"]))
            {
                string path = Request.Path;
                var selectItem = items.FirstOrDefault((item) => item.Link == path);
                if (selectItem != null)
                {
                    selectItem.Link = string.Empty;
                }
            }
            return View(items);
        }
    }
}

частичное представление компонента (Default.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

Доработаем метод Invoke() компонента следующим образом:

public IViewComponentResult Invoke(List<MenuItem> items)
{
    if (Request.Query.ContainsKey("exclude") && Convert.ToBoolean(Request.Query["exclude"]))
    {
        string path = Request.Path;
        var selectItem = items.FirstOrDefault((item) => item.Link == path);
        if (selectItem != null)
        {
            selectItem.Link = string.Empty;
        }
    }
    return View(items);
}

Здесь мы, используя свойство Request, проверяем наличие параметра запроса с именем exclude и, если этот параметр равен true, то удаляем ссылку на элемент, совпадающий с Url страницы на которой загружается компонент. По-хорошему, конечно, стоит проверить, действительно ли в параметре содержится то, что можно преобразовать в bool, но, в качестве примера, мы это проверку опустим.  Также, немного изменим частичное представление компонента (Default.cshtml):

@using AspMvcComponents.Components;
@using AspMvcComponents.Components.Menu
@model IEnumerable<MenuItem> 

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

Теперь, для наглядности, добавим наш компонент в ещё одно представление, которое создается по умолчанию в шаблонном проекте ASP.NET Core MVC — Privacy.cshtml:

@addTagHelper *, AspMvcComponents
@using AspMvcComponents.Components;
@using AspMvcComponents.Components.Menu

@{
    ViewData["Title"] = "Privacy Policy";
}
<h1>@ViewData["Title"]</h1>

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

<p>Use this page to detail your site's privacy policy.</p>

Проверим работу компонента:

Таким образом мы смогли из компонента представления получить доступ к контексту запроса, проверить наличие параметра запроса и изменить логику работы компонента, используя полученные данные.

Итого

Наследование компонента представления от ViewComponent позволяет нам не только использоваться для рендеринга частичные представления, но и воспользоваться рядом полезных свойств, таких как контекст запроса, данные о маршруте, данные, передаваемые в представление (ViewData/ViewBag) и т.д.

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