View Components in ASP.NET Core MVC
View components are reusable pieces of UI that combine rendering logic and a view. They're similar to partial views but can contain their own ViewComponent
class, allowing for more complex behavior, data retrieval, and dependency injection.
When to Use a View Component
- Displaying dynamic content that requires logic (e.g., navigation menus, sidebars, or promotional content).
- Encapsulating rendering logic that would otherwise clutter a controller or view.
- Reusing UI sections across multiple pages with different data.
Creating a View Component
1. Add a class that inherits from Microsoft.AspNetCore.Mvc.ViewComponent
:
using Microsoft.AspNetCore.Mvc;
public class WeatherSummaryViewComponent : ViewComponent
{
private readonly IWeatherService _service;
public WeatherSummaryViewComponent(IWeatherService service)
{
_service = service;
}
public async Task<IViewComponentResult> InvokeAsync()
{
var forecast = await _service.GetWeeklyForecastAsync();
return View(forecast);
}
}
2. Add a view for the component under /Views/Shared/Components/WeatherSummary/Default.cshtml
:
@model IEnumerable<WeatherForecast>
<div class="weather-summary">
<h3>Weekly Forecast</h3>
<ul>
@foreach (var day in Model)
{
<li>
<strong>@day.Date.ToString("dddd")</strong>:
@day.Summary (@day.TemperatureC°C)
</li>
}
</ul>
</div>
Invoking a View Component
Use the Component
tag helper or the Component.InvokeAsync
method in Razor:
<!-- Tag helper syntax -->
<vc:weather-summary />
<!-- Method invocation -->
@await Component.InvokeAsync("WeatherSummary")
Parameters
Pass parameters to a view component by defining an Invoke
or InvokeAsync
method with arguments:
public async Task<IViewComponentResult> InvokeAsync(int days)
{
var forecast = await _service.GetForecastAsync(days);
return View(forecast);
}
Invoke with arguments:
<vc:weather-summary days="5" />
@await Component.InvokeAsync("WeatherSummary", new { days = 5 })
Best Practices
- Keep view component logic lightweight; delegate heavy work to services.
- Prefer async
InvokeAsync
methods to avoid blocking threads. - Use descriptive names that reflect the component's purpose.