Quick introduction to View Components in ASP.NET Core MVC

View components is newly introduced feature in ASP.NET Core MVC in replacement of partial views. View components are very similar to partial views and allow users to write reusable components without using model binding. View components support async as well as they render in chunk instead of the whole response. Previously, ChildActions used to implement controller logic, on introducing view components ChildActions feature is removed from ASP.NET Core.

In
this article we will create a simple recent article list(widget) using
view components and see how effectively it will replace partial view.

Create a view component

A view component consists of two parts, the class (typically derived
from ViewComponent) and the result it returns (typically a view). Like
Controller view component supports POCO, methods and dependency injections.

A view component can be created by any of following methods,

Deriving from ViewComponent

Decorating a class with the [ViewComponent] attribute

have name ends with the suffix ViewComponent

Like controllers, view components must be public, non-nested, and non-abstract classes. As a view component does not take part in controller life cycle, we cannot use Filters in it.

Let's start, create a new class with suffix "ViewComponent"(as we are doing while creating a controller).

A view component defines its logic in an InvokeAsync method that returns an IViewComponentResult. Parameters come directly from invocation of the view component, not from model binding. A view component never handles a request. Typically initializes a model and passes it to a view by calling the ViewComponent View method. View components are not reachable directly as an HTTP endpoint, they are invoked from your code (usually in a view).

Here, we have initialized ArticleService class and using it's object we are
calling GetRecentArticles to retrieve a list of articles. That will
displays the same output as shown at the end of the article.

Create a view for view component

To create a view for view component we need to follow conventions. The runtime searches for the view in the following paths:

Views/<controller_name>/Components/<view_component_name>/<view_name>

Views/Shared/Components/<view_component_name>/<view_name>

As per conventions we need to create Views/Home/Components/RecentArticles/Default.cshtml or Views/Shared/Components/RecentArticles/Default.cshtml. You can see the structure in below image

Have you noticed one thing, why I had used RecentArticles instead of RecentArticlesViewComponents?, This is because I declared view component name RecentArticles using [ViewComponent(Name = "RecentArticles")] attribute in view component class. If you are not doing the same, then RecentArticlesViewComponent would be much preferred then RecentArticles while creating the view.

Invoking a view component

Let's create Default.chtml view for a view component. In view, we are simply looping the IEnumerable<Articles> and displaying the article information one by one.Default.chtml

Once you have registered the new service with the dependency injection container, you can either inject the service into the constructor of a view component class or the property of a view component class.RecentArticlesViewComponents.cs

Declare ArticleService object in the class. Inject service object using constructor injection. You can get GetRecentArticles() using the same object without creating a new object of service as previous.
I have used constructor injection to inject services in view component. Now I can access GetRecentArticles() method using the same object I had declared in the class.