Introduction
View Components are a powerful feature in ASP.NET Core MVC that allows you to encapsulate complex UI logic into reusable components. They are designed to render fragments of HTML, much like Razor views, but with the added benefit of having their own dedicated logic and data fetching capabilities.
What are View Components?
A View Component is a self-contained unit that:
- Encapsulates presentation logic: It handles data retrieval and rendering for a specific part of a page.
- Is reusable: You can invoke it from multiple places within your application.
- Does not depend on controller actions: It operates independently of the typical MVC controller-action pipeline.
When to Use View Components
View Components are ideal for scenarios where you need to:
- Render a partial view that is not tied to a specific model.
- Display data that requires complex logic or data fetching.
- Create reusable UI elements like navigation menus, sidebars, or featured product lists.
- Avoid cluttering your Razor views with data retrieval logic.
View Components are conceptually similar to "Presenter-Views" in other frameworks or to partial views with server-side logic. They are NOT related to UI Components in Blazor.
Creating a View Component
A View Component consists of two main parts: the View Component class and optionally, a View Component view.
View Component Class
A View Component class inherits from Microsoft.AspNetCore.Mvc.ViewComponent
. It typically contains a method named InvokeAsync
which performs the business logic and returns a Task<IViewComponentResult>
.
Example: Simple View Component Class
using Microsoft.AspNetCore.Mvc;
using System.Threading.Tasks;
public class HelloWorldViewComponent : ViewComponent
{
public async Task<IViewComponentResult> InvokeAsync()
{
// Simulate fetching some data
var message = "Hello from View Component!";
return View(message); // Returns the default view with the message
}
}
View Component View
By default, a View Component looks for a view file in the following locations:
Views/{ControllerName}/Components/{ComponentName}/Default.cshtml
Views/Shared/Components/{ComponentName}/Default.cshtml
If you don't specify a view name when invoking, it will use Default.cshtml
. You can also specify a different view name.
Example: Default.cshtml for HelloWorldViewComponent
@model string
<div class="alert alert-info">
<h4>View Component Output</h4>
<p>@Model</p>
</div>
Invoking a View Component
You can invoke View Components in two primary ways:
From a Razor View
Use the await Component.InvokeAsync(...)
helper method in your Razor views.
Example: Invoking HelloWorldViewComponent in a Razor View
<!-- In a .cshtml file -->
<div>
<h3>Content Before View Component</h3>
@await Component.InvokeAsync("HelloWorld") <!-- Invokes the HelloWorldViewComponent -->
<h3>Content After View Component</h3>
</div>
When invoking, you can pass arguments to the InvokeAsync
method. These arguments are passed to the InvokeAsync
method if it has matching parameters.
Example: Invoking with Arguments
View Component Class (MyGreetingViewComponent.cs):
public class MyGreetingViewComponent : ViewComponent
{
public async Task<IViewComponentResult> InvokeAsync(string name)
{
return View("Default", $"Hello, {name}!");
}
}
Razor View (.cshtml):
@await Component.InvokeAsync("MyGreeting", new { name = "Alice" })
<!-- Output: Hello, Alice! -->
From a Controller
While less common, you can also invoke a View Component from a controller action. This is useful if the logic needs to be triggered by a controller's workflow.
Example: Invoking from a Controller
using Microsoft.AspNetCore.Mvc;
public class HomeController : Controller
{
public IActionResult Index()
{
// You can directly return a ViewComponentResult
return ViewComponent("HelloWorld");
}
public IActionResult ShowGreeting()
{
// Or pass data to a ViewComponentResult
return ViewComponent("MyGreeting", new { name = "Bob" });
}
}
View Components Without a View
It's possible for a View Component to directly return HTML content without using a separate .cshtml
file. This is achieved by returning an HtmlContentResult
or by directly writing to the response.
Example: View Component Directly Returning HTML
public class SimpleHtmlViewComponent : ViewComponent
{
public async Task<IViewComponentResult> InvokeAsync()
{
// Directly return an HTML string
return Content("<div class='bg-primary text-white p-2'>This is pure HTML content!</div>");
}
}
Example Scenarios
- Navigation Menu: Fetch user roles and generate a dynamic navigation menu.
- Shopping Cart Summary: Display the number of items in the user's cart.
- Latest News Feed: Retrieve and display the latest articles from a data source.
- User Profile Widget: Show a small widget with user's avatar and name.
View Components are a fundamental part of building robust and maintainable ASP.NET Core applications, promoting code reuse and separation of concerns.