ASP.NET Core MVC View Components

Enhance Razor page rendering with reusable components.

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.