Search code examples
c#asp.net-corerazor-pagesview-components

ViewComponent TagHelpers not rendering


There are a few similar questions, but none of which seem to be recent, and Microsoft's documentation doesn't list any special steps: https://learn.microsoft.com/en-us/aspnet/core/mvc/views/view-components?view=aspnetcore-6.0

The @await Component.InvokeAsync("TopBooks"... works without issue, but the <vc:top-books /> does not render. I added @addTagHelper *, WebApplication1 to the top of Index.cshtml but the TagHelper doesn't work. If you inspect the source it's just written out as is.

I also tried adding @addTagHelper *, WebApplication1 to _ViewImports.cshtml instead with no difference in behaviour.

I created a basic ASP.NET Core Razor Pages .NET 6 application in Visual Studio 2022. File > New > ASP.NET Core Web App > Next until completed

I then created a very simple ViewComponent and model:

public class TopBooksViewComponent : ViewComponent {
    public IViewComponentResult Invoke(MyBook book) {
        return View(book);
    }
}

saved as Components/TopBooksViewComponent.cs

public class MyBook {
    public string Author { get; set; }

    public string Title { get; set; }
}

saved as Models/MyBook.cs

Next, I created the View:

@model WebApplication1.Models.MyBook

<h1>Top Books view component</h1>

<p>@Model.Title by @Model.Author</p>

saved as Pages/Shared/Components/TopBooks/Default.cshtml

Then, to try it out I opened Pages/Index.cshtml and modified it to this:

@page
@using WebApplication1.Components
@using WebApplication1.Models
@model IndexModel
@addTagHelper *, WebApplication1

@{
    ViewData["Title"] = "Home page";
}

<div class="text-center">
    <h1 class="display-4">Welcome</h1>
    @await Component.InvokeAsync("TopBooks", new MyBook() {Author = "John Smith", Title = "How to do stuff!"})
    
    <vc:top-books Author="Shepard" Title="The Reapers are coming!"></vc:top-books>
</div>

As I said, the @await Component.InvokeAsync works with no problem, but the TagHelper does nothing. As far as I can tell there isn't any other special setup required and it comes down to @addTagHelper *, WebApplication1 not working. However, I am not sure what else I can change it to. WebApplication1 is the name of my project as well.


Solution

  • The 2 string arguments Author and Title passed via the taghelper below, don't match the signature of the Invoke method.

    <vc:top-books Author="Shepard" Title="The Reapers are coming!"></vc:top-books>
    

    That Invoke method expects a MyBook instance.

    public IViewComponentResult Invoke(MyBook book)
    

    The taghelper should pass a MyBook object like below.

    <vc:top-books book="@(new MyBook { Author = "Shepard", Title = "The Reapers are coming!" })"></vc:top-books>