Microsoft Developer Network
View Components are a powerful feature in ASP.NET Core that allow you to encapsulate reusable rendering logic. They are a prime example of the Model-View-Controller (MVC) pattern's flexibility, enabling you to create components that can be rendered in any Razor page or view.
Unlike partial views, View Components are designed for more complex rendering scenarios. They have their own dedicated model and can execute logic, making them ideal for tasks such as:
To create a View Component, you typically need two main parts:
Microsoft.AspNetCore.Mvc.ViewComponent
and contains the logic to prepare data and select a view.Default.cshtml
) located in the Views/Shared/Components/{ComponentName}/
folder or within the specific view's folder.Let's create a simple View Component that displays a list of menu items.
using Microsoft.AspNetCore.Mvc;
using System.Collections.Generic;
namespace MyWebApp.ViewComponents
{
public class MenuViewComponent : ViewComponent
{
public IViewComponentResult Invoke()
{
var menuItems = new List<string>
{
"Home",
"About",
"Services",
"Contact"
};
return View(menuItems);
}
}
}
Create a folder named Menu
inside Views/Shared/Components/
. Inside this folder, create a file named Default.cshtml
.
@model IEnumerable<string>
<ul class="menu-list">
@foreach (var item in Model)
{
<li><a href="#">@item</a></li>
}
</ul>
<style>
.menu-list {
list-style: none;
padding: 0;
margin: 0;
display: flex;
gap: 15px;
font-weight: bold;
}
.menu-list li a {
text-decoration: none;
color: #005a9e;
transition: color 0.3s ease;
}
.menu-list li a:hover {
color: #0078d4;
}
</style>
You can invoke a View Component from any Razor view or page using the <vc:component-name>
tag helper syntax.
In your _Layout.cshtml
or any other view, add the following:
<header>
<!-- Other header content -->
<nav>
<vc:menu></vc:menu>
</nav>
<!-- Other header content -->
</header>
Default.cshtml
within the component's folder.
View Components can accept parameters to customize their behavior and data. You can define parameters by overriding the InvokeAsync
method and accepting parameters, or by creating separate methods named InvokeAsync(params...)
.
Let's modify our Menu
View Component to accept a parameter for the active item.
using Microsoft.AspNetCore.Mvc;
using System.Collections.Generic;
using System.Linq; // Added for LINQ
namespace MyWebApp.ViewComponents
{
public class MenuViewComponent : ViewComponent
{
public IViewComponentResult Invoke(string activeMenuItem)
{
var menuItems = new List<MenuItem>
{
new MenuItem { Name = "Home", Url = "/" },
new MenuItem { Name = "About", Url = "/about" },
new MenuItem { Name = "Services", Url = "/services" },
new MenuItem { Name = "Contact", Url = "/contact" }
};
// Mark the active item
foreach (var item in menuItems)
{
if (item.Name.Equals(activeMenuItem, System.StringComparison.OrdinalIgnoreCase))
{
item.IsActive = true;
}
}
return View(menuItems);
}
}
public class MenuItem
{
public string Name { get; set; }
public string Url { get; set; }
public bool IsActive { get; set; }
}
}
Default.cshtml
):
@model IEnumerable<MyWebApp.ViewComponents.MenuItem>
<ul class="menu-list">
@foreach (var item in Model)
{
<li class="@(item.IsActive ? "active" : "")">
<a href="@item.Url">@item.Name</a>
</li>
}
</ul>
<style>
.menu-list {
list-style: none;
padding: 0;
margin: 0;
display: flex;
gap: 15px;
font-weight: bold;
}
.menu-list li a {
text-decoration: none;
color: #005a9e;
transition: color 0.3s ease;
}
.menu-list li a:hover {
color: #0078d4;
}
.menu-list li.active a {
color: #d33030; /* A distinct color for active item */
font-weight: bold;
text-decoration: underline;
}
</style>
In your Razor view:
<nav>
<vc:menu active-menu-item="About"></vc:menu>
</nav>
View Components provide a robust and organized way to handle reusable UI logic in ASP.NET Core applications. By separating concerns and promoting modularity, they contribute significantly to maintainable and scalable web development.
Explore further to learn about asynchronous invocation, caching, and more advanced patterns for View Components.