Introduction
View Component is a newly introduced feature in ASP.NET Core MVC. It is very similar to partial view but is very powerful as compared to it. It does not use model binding but works only with the data we provide when calling into it. View Component has the following features.
- It also includes SOC (separation-of-concerns) and testability benefit
- It can have business logic as well as parameter
- It is invoked from layout page
- It renders chunk rather than a whole response
The View Component includes two parts: the class that is derived from ViewComponent abstract class and the result returns, i.e., View in most cases. The View Component class is similar to Controller class, it might have POCO.
A View Component class can be created in the following ways.
- Class deriving from ViewComponent abstract class
- Decorating a class with ViewComponent attribute or attribute that derived from ViewComponent attribute
- Creating class with suffix ViewComponent (same as Controller class)
Same as Controller class, View Component class must be non-abstract, public, and non-nested. This class fully supports constructor dependency injection. It does not take part in the Controller lifecycle so that we cannot use filters in the view component.
The View Component defines logic in InvokeAsync method which returns IViewComponentResult. Required parameters directly come from invocation of the View Component. It never handles a request directly. The View Component initializes the model and passes to the View using "View" method. They are not directly reachable as an HTTP endpoint. They must be invoked from the code.
Example of ViewComponent class
- namespace testCore
- {
- using System.Collections.Generic;
- using System.Threading.Tasks;
- using Microsoft.AspNetCore.Mvc;
-
- public class EmployeeList : ViewComponent
- {
- public async Task<IViewComponentResult> InvokeAsync(int noOfEmployee)
- {
- List<Employee> items = new List<Employee>();
- for (var i = 0; i <= noOfEmployee; i++)
- {
- items.Add(new Employee { Id = i, Name = "Emp " + i.ToString() });
- }
- return View(items);
- }
- }
- }
ViewComponent attribute can be used to change the name of the view component. For example, if we have class named "TestViewComponent" and want to set view component name to "EmployeeList1", this can be done using ViewComponent attribute.
- [ViewComponent(Name="EmployeeList1")]
- public class TestViewComponent : ViewComponent
- {
- ....
- ....
- }
Same as Controller class, view component searches for the view runtime in following paths.
- View/<Controller Name>/ Components/ <View Component name > / <View Name>
- Views/Shared/Components/<View Component Name>/ <View Name>
The default view name is "Default" for the view component. It means that our view name must be "Default.cshtml". We can assign a different name to the view of view component and this name must be passed to view method.
How to invoke View Component from View
The InvokeAsync method is used to invoke the view component. This method accepts two parameters: name of the view component and parameter. The parameter is anonymous type.
Syntax
- @Component.InvokeAsync("Name of view component", <parameters: anonymous type >)
Example
- @await Component.InvokeAsync("EmployeeList", new { noOfEmployee = 4 })
Invoking a view component in View as a Tag Helper
Tag Helper was introduced in ASP.NET Core 1.1 and higher. For tag helper, Pascal case class and method parameter are translated into lower kebab case. We have to use "vc" element (<vc></vc>) to invoke the view component as a tag helper. It can be specified as following.
- <vc:[view component name] parameter1="value"
- parameter2="value">
- </vc:[view component name]>
Example
- <div class="row">
- <vc:employee-list no-of-employee="5">
- </vc:employee-list>
- </div>
We must register the assembly that contains the view component using @addTagHelper directive if we use a view component as a tag helper. For example, if our view component assembly is named "ViewComponent", add the following code to _viewImports.cshtml file.
- @addTagHelper *, ViewComponent
Invoking a view component from a Controller class
Mostly, view components are invoked from a view, but we can also invoke them from the Controller method. The view component does not have endpoint as controller class, so we can implement controller action that returns ViewComponentResult.
Example
- public IActionResult Index3()
- {
- return ViewComponent("EmployeeList", new { noOfEmployee = 3});
- }
Specifying a view name in ViewComponent
The complex view component might require to return non default view based on some condition. In the following example, ViewComponent will return EmployeeList view if the paramter noOfEmployee value is greater than 5.
- public async Task<IViewComponentResult> InvokeAsync(int noOfEmployee)
- {
- List<Employee> items = new List<Employee>();
- for (var i = 0; i <= noOfEmployee; i++)
- {
- items.Add(new Employee { Id = i, Name = "Emp " + i.ToString() });
- }
- if (noOfEmployee > 5)
- {
- return View("EmployeeList", items);
- }
- return View(items);
- }
EmployeeList.cshtml
- @model IEnumerable<testCore.Employee>
-
- <h3>Employee List</h3>
- <ul>
- @foreach (var emp in Model)
- {
- <li>@emp.Name</li>
- }
- </ul>
Output
If view is not found at the desired location, the system will throw an exception. This is the same behavior as controller class. In the above example, I have changed the view name to “EmployeeList1” and tried to execute but the system will throw an error.
Summary
View Component is an important feature of ASP.NET Core. It is very similar to the Partial View. In this article, we learned how to use View Component in ASP.NET Core.
You can view or download the source code from the following
GitHub link.