View components

View components are a new feature introduced in ASP.NET Core, they are almost similar to Partial Views but is more powerful. When you use Partial Views, you have dependency over the Controller. However, when you use the ViewComponent attribute, you do not have to depend on the Controller, so we will establish separation of concerns and have better testability. Even though the existing Partial View HTML helper is still supported, it is preferable to use the View component whenever you want to show a reusable piece of information when you are using .NET Core.

Creating a View component

You can create a ViewComponent using any of the following:

  • Create a class by deriving from the ViewComponent attribute
  • Decorate a class with the [ViewComponent] attribute or derive it from the class that has the [ViewComponent] attribute
  • You can use the convention by creating a class that ends with a suffix ViewComponent attribute

Whatever option you choose, this ViewComponent should be public, non-nested, and non-abstract classes.

Like Controllers, you can use the Dependency Injection (via a constructor) in the ViewComponent attribute as well. As the ViewComponent attribute is separate from the Controller lifecycle, you may not be able to use the action filters in ViewComponents.

There is a method called Invoke (or InvokeAync, the asynchronous equivalent of Invoke), that will return the IComponentViewResult interface. This method is similar to the action method of the Controller that will return the View.

Let's get our hands dirty by creating a ViewComponent attribute.

Create a new folder called ViewComponents in your project and a new class called SimpleViewComponent, as shown in the following screenshot:

Creating a View component

The SimpleViewComponent file that we created will look like the following:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNet.Mvc;

namespace Chapter4.ViewComponents
{
  public class SimpleViewComponent :ViewComponent
  {
    public IViewComponentResult Invoke()
    {
      var data = GetSampleData();
      return View(data);
    }
    /// <summary>
    /// This is a simple private method to return some dummy data
    /// </summary>
    /// <returns></returns>

    private List<string> GetSampleData()
    {
      List<string> data = new List<string>();
      data.Add("One");
      data.Add("Two");
      data.Add("Three");
      return data;
    }
  }
}

We just have a couple of methods, one to populate the data and the other is the Invoke method where we will render the View.

Once you have created the ViewComponent attribute, you will need to include the ViewComponent namespace in the Views\_ViewImports.cshtml file so that the ViewComponents attributes can be available for all the Views. The highlighted code snippet in the following is added to the View:

@using Chapter4
@using Chapter4.Models
@using Chapter4.ViewComponents

@addTagHelper "*, Microsoft.AspNet.Mvc.TagHelpers"

We have created the ViewComponent and made them available to all of the Views. A simple action method in the HomeController file just returns the View:

public ActionResult Sample()
{
return View();
}

In the associated View, we can just invoke the component as shown in the following code snippet:

<p>
  This is a sample web page <br/>
  <div>
    @Component.Invoke("Simple")
  </div> 
</p>

When you invoke the component, it will search in the following two folders:

  • The Views<controller_name>Components<view component name><view name> folder
  • The ViewsSharedComponents<view_component_name>/<view_name> folder

The default View name of the View component is Default, which makes your file name for the View Default.cshtml. So, we will need to create the Default.cshtml file in ViewsSharedSimpleDefault.cshtml folder, as shown in the following screenshot:

Creating a View component

In the the View (Default.cshtml file) of the ViewComponent file, we are just iterating the items in the model and displaying them as an unordered list item, as shown in the following code:

@model IEnumerable<string>

<h3> Sample list</h3>
<ul>
  @foreach(var item in Model)
  {
    <li>@item</li>
  }
</ul>

When you run the application and access the URL (http://localhost:50132/Home/Sample), you should see the following output:

Creating a View component

The first line, This is a sample web page, comes from the parent View file (sample.cshtml) whereas the subsequent list comes from ViewComponent attribute.

The ViewComponent attributes are usually referred in the Views. However, if you want to call the ViewComponent directly from your Controller, you can do so.

I have called the Sample action method to call the Simple ViewComponent directly instead of calling it through some other View as follows:

public ActionResult Sample()
{
  return ViewComponent("Simple");
  //return View();
}

Creating a View component

Thus, these ViewComponents have far more flexibility and features, such as Dependency Injection, when compared to old HTML Partial Views. This ensures ViewComponents are separately tested.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset