Stay updated

Let’s convert the ASP.NET MVC Partial View with ASP.NET Core View Components
Kestrel build me up!
Tuesday, March 26, 2019

During the porting from ASP.NET MVC 5.0 to ASP.NET Core made on our CMS “WebRight”, I should face a problem: the widget management in WebRight. Actually, these widgets have been managed with the use of some Partial View, which would be redirected within the views, thanks to the helper HTML.RenderAction. Unfortunately, the latter is no more available on ASP.NET Core.

No sweat anyway: ASP.NET Core introduces the View Components to manage these usages. This is a new feature, that allows us to redirect HTML to a Razor page. These are generated from a C# class, that extend the base ViewComponent class, and they are typically associated to a Razor file to generate the markup we need. 

I would like to tell you how to write some View Component, using Visual Studio 2017 and ASP.NET CORE and how we bring this new functionality in WebRight.

As first step, we must create a new Web Application ASP.NET CORE:

When we are requested to choose which Web App we want to create, we will select Web Application, which will create a simple website, using new ASP.NET Core Razor pages:

The selected template creates for us a defined folder structure, inside which there’s the directory Pages. Within this directory, we create a sub folder, where we can move our View Component:

Now we create a folder TestViewComponent , that contains a C# file and a Razor View Page, that will compose our View Component and we call it:

Let’s implement our View Component (our base class), that have an empty constructor and an Invoke method with a single parameter.

using Microsoft.AspNetCore.Mvc;
namespace ViewComponentsExample.Pages.Components.TestViewComponent
    public class TestViewComponentViewComponent : ViewComponent
        public TestViewComponentViewComponent() { }
        public IViewComponentResult Invoke(string nome)
            return View("Default", nome);

Our View Razor will be very simple: it has only two lines of code. The first one tells us which type the model, that will be passed to the view, would be, the second one will redirect the model to a tag h2.

@model string

Now we have a complete View Component. In order to use it, we can use a Razor page, just as we did with HTML.RenderAction, , then we create a new Razor View and we call it TestViewComponentPage

We can display our View Component in two ways: using the InvokeAsync InvokeAsync to recall the class or with a HTML custom tag.

Tthe first method we display is InvokeAsync: we should pass in input to it a first parameter with the name of the component (name of the class without the suffix ViewComponent) and the second parameter is an anonymous type. This is our complete page:

@model ViewComponentsExample.Pages.TestViewComponentPageModel
    <h1>Demo component Async</h1>
    @await Component.InvokeAsync("TestViewComponent", new {
    nome = "Mio primo componente"

if we start the application, this is the result of what we wrote until now:

As we reveal before, another method exists to use View Component within our Razor pages: we can create a HTML custom tag to insert inside the page, an ASP.NET Core functionality called Tag Helpers.

Look at how to use Tag Helper to invoke our View Component. Below, you can find how our Razor page will change compared to the previous one.

@model ViewComponentsExample.Pages.TestViewComponentPageModel
@addTagHelper *, ViewComponentsExample
<!DOCTYPE html>
    <meta name="viewport" content="width=device-width" />
    <title>Demo component con Tag helper</title>
    <h1>Demo component con Tag helper</h1>
    <vc:test-view-component nome="mio componente con tag helper">

All I need to do is to add the line @addTagHelper*, ViewComponentsExample that simply says to use all defined Tag Helper in my assembly. Now, I can reference my component in HTML body with the prefix vc to indicate view components. The tag name is only the name of our View Component, divided in Kebab casing (test-view-component). The most interesting part of this method is that I shouldn’t modify the code of my class to permit the Tag Helper to work!

How did we use all this material in WebRight? Our previous implementation manages the widgets directly from the unique controller, present in the application’s core, using this simple code:

[Route("widget/{widget_name}", Name = "WebRightWidgetDefaultGet")]
public PartialViewResult Widget(string widget_name, WebRightWidgetArguments arguments)
    IWebRightWidget widget = this.widgetFactory.GetWidgetByName(widget_name);
    return PartialView(
        string.Format("_{0}{1}", widget_name, arguments.ViewVersionName),
        widget.GetViewModel(getCurrentCultureName(), arguments.Parameters));

This approach allows us to write HTML helper, for whom we specify the name of the widget to be recalled and pass possible parameters, that can be needed to widget purpose. Here is an example of a code of a helper, that recall Menu widgets:

public static MvcHtmlString Menu(this HtmlHelper html, string categoryName, string viewVersionName = "")
    return html.Action(
            widget_name = "WebRightMenuWidget",
            arguments = new WebRightWidgetArguments
                ViewVersionName = viewVersionName,
                Parameters = new object[] { categoryName }

These two code’s section permitted us to easily redirect a widget to any page in our application:


how did we modify this behavior to use new ASP.NET Core View components? Below you find our View Component, that substitutes the action widget of the controller, which I described you:

public class WidgetViewComponent : ViewComponent
    private readonly IWebRightWidgetFactory widgetFactory = null;
    public WidgetViewComponent(IWebRightWidgetFactory wf)
        this.widgetFactory = wf;
    public async Task<IViewComponentResult> InvokeAsync(string name, string culture = null, string viewVersionName = null, object[] parameters = null)
        IWebRightWidget widget = this.widgetFactory.GetWidgetByName(name);
        return View($"{name + viewVersionName}", widget.GetViewModel(culture, parameters));

As you can see, the class is relatively simple: It has an InvokeAsync method, that is recalled with some parameters (some of them, were those used on the action Widget of the controller)

What is now lacking is to substitute the use of Html Helper. This modification results simple too: all you need to do is to recall the InvokeAsync method within one of our Razor pages, in order to redirect the widget we need. This is a concrete example:

@await Component.InvokeAsync("Widget", new { name = "TestWidget" })

As I explained, I prefer the approach with TagHelper to redirect the ViewComponent. We can do another small modification to our page, that becomes:

<vc:widget name="TestWidget"></vc:widget>

To initialize TagHelper, I just add this line to the applicaiton’s Layout page:

@addTagHelper *, WebRight

We can close the overview on the use of View Component. I wish I was able to inspire your curiosity on this ASP.NET Core functionality.

See you next!