A view component renders a self-contained section of an ASP.NET Core Razor page. Use one when that section needs its own business logic or data access as well as HTML—for example, a shopping cart or dynamic navigation menu. Unlike a partial view, it can do more than encapsulate markup; unlike a legacy child action, it does not invoke a controller action. section 17.4.3 section 32.2
To create and use one:
- Derive a class from ViewComponent and implement InvokeAsync(). Inject any services the component needs through its constructor. section 32.2 section 32.5
- Put its view in Pages/Shared/Components/<Name>/. If no view name is specified, the component looks for Default.cshtml. section 32.5
- Invoke it from a Razor view. HTML attributes can supply parameters to InvokeAsync(); alternatively, call Component.InvokeAsync(). section 32.2 section 32.5
Recipes for the current user
A MyRecipesViewComponent can use injected recipe and user services to select recipes for the logged-in user, then render them separately from the page’s main content. A Razor view can request three recipes with <vc:my-recipes number-of-recipes="3"></vc:my-recipes>, or call @await Component.InvokeAsync("MyRecipes", new { numberOfRecipes = 3 }). section 32.2
Listing 32.5 A custom view component to display the current user’s recipes
public class MyRecipesViewComponent : ViewComponent #1
{
private readonly RecipeService _recipeService; #2
private readonly UserManager<ApplicationUser> _userManager; #2
public MyRecipesViewComponent(RecipeService recipeService, #2
UserManager<ApplicationUser> userManager) #2
{ #2
_recipeService = recipeService; #2
_userManager = userManager; #2
} #2
public async Task<IViewComponentResult> InvokeAsync( #3
int numberOfRecipes) #4
{
if(!User.Identity.IsAuthenticated)
{
return View("Unauthenticated"); #5
}
var userId = _userManager.GetUserId(HttpContext.User); #6
var recipes = await _recipeService.GetRecipesForUser( #6
userId, numberOfRecipes);
return View(recipes); #7
}
}
The class listing shows ViewComponent inheritance, constructor-injected services, and an InvokeAsync method that accepts the recipe count. section 32.2

