Mar 31, 2018

ASP.NET Core 2.0 MVC View Components

Going to talk more about Asp.Net Core newly introduced feature of view components for reusable UI.

Introduction
It's similar to partial views, but it's very powerful to compare partial view. View components don't use model binding, and only depend on the data provided when calling into it

View Component has the following features.
  • Renders a chunk rather than a whole response.
  • It can have business logic as well as parameter
  • Is typically invoked from a layout page.
  • It also includes SOC (separation-of-concerns) and testability benefit
View Component represents in two parts.
1. View Component class typically derived from ViewComponent.
2. Return result as HTML typically a View.

The View Component class is similar to Controller class, it might have POCO.

A View Component class can be created in any of the following ways.

  • Class deriving from ViewComponent abstract class
  • Decorating a class with ViewComponent attribute or attribute that derived from ViewComponent attribute
  • Creating a class with suffix ViewComponent (like Controller class name)
Like controllers, view components must be public, non-nested, and non-abstract classes. This class fully supports constructor dependency injection. It does not take part in the controller lifecycle, which means you can't use filters in a view component

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

Let's create a View Component class so it's easy to understand.

Creating a view component
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using AspNetCoreViewComponent.Models;
using Microsoft.AspNetCore.Mvc;

namespace AspNetCoreViewComponent.ViewComponents
{
    public class StudentListViewComponent : ViewComponent
    {
        public async Task InvokeAsync(int noOfStudent)
        {
            var students = new List();
            for (var i = 0; i <= noOfStudent; i++)
            {
                students.Add(new Student { Id = i, Name = "Student " + i.ToString() });
            }
            return View(students);
        }
    }
}

You can see a name of the class is StudentListViewComponent and it's inherited from the ViewComponent abstract class.

ViewComponent attribute can be used to change the name of the view component. For example, if we have the class named XYZ and want to set view component name to StudentList, this can be done using ViewComponent attribute.
 

[ViewComponent(Name = "StudentList")]
    public class XYZ : ViewComponent
    {
       ......       
       .......
        
    }

The runtime searches for the view in the following paths:

  • Views//Components//
  • Views/Shared/Components//
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.

Invoking a view component
To use the view component, call the following inside a view:
 
@Component.InvokeAsync("Name of view component", "anonymous type") 
The parameters will be passed to the InvokeAsync method. The StudentList view component invoked from the Views/Students/Index.cshtml view file. In the following, the InvokeAsync method is called with two parameters:
 
@await Component.InvokeAsync("StudentList", new { noOfStudent = 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 () to invoke the view component as a tag helper. It can be specified as follows.
 
  
    

Example
 
  
      

Note: In order to use a View Component as a Tag Helper, you must register the assembly containing the View Component using the @addTagHelper directive. For example, if your View Component is in an assembly called "ViewComponents", add the following directive to the _ViewImports.cshtml
file:
 
@addTagHelper *, ViewComponents

Invoking a view component directly from a controller
Mostly, view components are invoked from a view, but you can invoke them directly from a controller method. While view components don't define endpoints like controllers, so we can implement controller action that returns ViewComponentResult.

 
public IActionResult Index()
{
    return ViewComponent("StudentList", new { noOfStudent = 4});
}


Specifying a view name
The complex view component might require returning non-default view based on some condition. In the following example, ViewComponent will return StudentList view if the noOfStudent value is greater than 4.
 
public async Task InvokeAsync(int noOfStudent)  
{  
    var students = new List();  
    for (var i = 0; i <= noOfStudent; i++)  
    {  
        students.Add(new Student { Id = i, Name = "Student " + i.ToString() });  
    }  
    if (noOfStudent > 4)  
    {  
        return View("StudentList", students);  
    }  
    return View(students);  
} 

StudentList.cshtml view created from Default.cshtml view and its look like following code.
 
@model IEnumerable

Students

    @foreach (var student in Model) {
  • @student.Id - @student.Name
  • }

Output
Both the syntax used to generate out as well conditional render view also handle in this output.



Hope you like the new feature View Component of the Asp.Net Core. For source code you can visit my Github repo https://github.com/kalpeshsatasiya/AspNetCoreViewComponents

No comments:

Post a Comment