ASP.NET Core 2.0 MVC View Components

Problem

How to reuse parts of web pages using View Components in ASP.NET Core MVC.

Solution

In an empty project, update Startup class to add services and middleware for MVC.

Add a Model to display in the View.

Add a Controller with action method returning ViewResult.

Add a parent View named Index.cshtml.

Add a View Component’s Model.

Add a View Component’s class.

Add a View Component’s View named as Default.cshtml.

Discussion

View Components are special type of Views rendered inside other Views. They are useful for reusing parts of a View or splitting a large View into smaller components.

Unlike Partial Views, View Components do not rely on Controllers. They have their own class to implement the logic to build component’s model and Razor View page to display HTML/CSS.

I like to think of them as mini-controllers, although this is not strictly correct but helps conceptualize their usage. Unlike Controllers, they do not handle HTTP requests or have Controller lifecycle, which means they can’t rely on filters or model binding.

View Components can utilize dependency injection, which makes them powerful and testable.

Creating

There are a few ways to create View Components. I’ll discuss the most commonly used (and best in my view) option.

  1. Create a class (anywhere in your project) and inherit from ViewComponent abstract class.

    • Name of the class, by convention, ends with ViewComponent.

  2. Create a method called InvokedAsync() that returns Task<IViewComponentResult>.

    • This method can take any number of parameters, which will be passed when invoking the component (see Invoking section below).

  3. Create Model e.g. via database etc.

  4. Call IViewComponentResult by calling the View() method of base ViewComponent. You could pass your model to this method.

    • Optionally you could specify the name of razor page (see Discovery section below).

The base ViewComponent class gives access to useful details (via properties) like HttpContext, RouteData, IUrlHelper, IPrincipal, and ViewData.

Invoking

View Components can be invoked by either,

  1. Calling @await Component.InvokeAsync(component, parameters) from the razor view.
  2. Returning ViewComponent(component, parameters) from a controller.

Here, “component” is a string value refereeing to the component class.

InvokeAsync() method can take any number of parameters and is passed using an anonymous object when invoking the View Component.

Below is an example of second option above. Notice that the second action method doesn’t work because the Razor page for the component is not under Controller’s Views folder, 

view components sln
Discovery

MVC will search for the razor page for View Component in the following sequence,

  1. Views/[controller]/Components/[component]/[view].cshtml
  2. Views/Shared/Components/[component]/[view].cshtml

Here matches either,

  1. Name of the component class, minus the ViewComponent suffix if used.
  2. Value specified in [ViewComponent] attribute applied to component class.

Also, [view] by default is Default.cshtml, however, it can be overwritten by returning a different name from the component class. Below the component returns a view named Info.cshtml,

jQuery

You could access View Components via jQuery as well. To do so enable the use of Static Files in Startup,

Add jQuery script file to wwwroot and use it in a page

Source Code

GitHub