liveBook · Manning

View component

As explained in Pro ASP.NET Core 7, Tenth Edition

The ViewComponent base class is the ASP.NET Core MVC base class that supplies view-component behavior and access to request context.

A view component supplies reusable content inside a parent Razor view. Its C# class obtains the data and chooses what to render, so a sidebar or cart summary need not be added to every action’s view model. Unlike a controller action or Razor Page, a view component cannot receive an HTTP request directly; its output is included in the parent view. section 24.2 section 9.2.2

Deriving from ViewComponent supplies view-component behavior and access to context such as RouteData and ViewBag. A component can also be discovered by a class name ending in ViewComponent with an Invoke or InvokeAsync method, or by the ViewComponent attribute. Components can live anywhere in the project; Components is the conventional folder. section 24.3 section 8.1.3

To build one, keep the data work in C# and the markup in Razor:

  • Inject a service through the component constructor. In Invoke, prepare the data and return View(data) to select the component’s default Razor view; a simple component can instead return a string. section 8.1.3 section 24.3
  • Put the markup in Views/Shared/Components/<component name>/Default.cshtml. The navigation view uses category names to generate links; the cart view uses a Cart to show item count and total value. section 8.1.3 section 9.2.2
  • Invoke the component from a parent view or shared layout with a vc element, such as <vc:navigation-menu />. The component’s result is inserted into that view’s output. section 8.1.3
Listing 8.8 Adding categories in the NavigationMenuViewComponent.cs file in the SportsStore/Components folder
using Microsoft.AspNetCore.Mvc;
using SportsStore.Models;

namespace SportsStore.Components {

    public class NavigationMenuViewComponent : ViewComponent {
        private IStoreRepository  repository;
                
        public NavigationMenuViewComponent(IStoreRepository repo) {
            repository = repo;
        }
                
        public IViewComponentResult Invoke() {
            return View(repository.Products
                .Select(x => x.Category)
                .Distinct()
                .OrderBy(x => x));
        }
    }
}

The navigation component injects IStoreRepository, selects distinct ordered categories in Invoke, and passes them to its Razor view. section 8.1.3

The parent view can pass values into Invoke or InvokeAsync. For a themeName parameter, supply theme-name on the vc element, or pass an object with a matching property to Component.InvokeAsync. Supply every required parameter: omitting one can leave the component absent without an error message. A default parameter value provides a fallback. section 24.5.1

Highlight the active category

Read RouteData.Values["category"] in Invoke, put the value in ViewBag.SelectedCategory, then let Default.cshtml give the matching link a different CSS class. A unit test can supply a ViewComponentContext with route data and inspect the returned view data. section 8.1.3

Use InvokeAsync when the data comes from an asynchronous API. Return a Task; Razor waits for it before inserting the result. A page-size component demonstrates this with an HttpClient request and a Default.cshtml view. It is applied the same way as a synchronous component. section 24.5.2

How Pro ASP.NET Core 7, Tenth Edition covers it

How deep it goes
Works through class discovery, injected data, Razor rendering, parent arguments, and request context rather than framework internals.
Examples
Builds category navigation and a shopping-cart summary, then demonstrates an asynchronous page-size display.
What it assumes
Assumes familiarity with C# classes and Razor views while demonstrating constructor injection and component invocation.
What you can do after
Build it from scratch: inject a service, implement Invoke, render a Razor view, and embed the result in a layout.
How it connects
Connects partial views, dependency injection, Razor layouts, route data, and tag helpers to embedded rendering.

Also explained in

Compare how 2 books explain view component →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Pro ASP.NET Core 7, Tenth Edition. The section links point to the parts of the book it draws on.