Search code examples
c#asp.net-corerazor-pagesasp.net-core-viewcomponentview-components

ViewComponent returns but model is null in view when using route value


I'm still new to Razor pages and view components, but have been around the block a few times with ASP.NET.

I'm not sure why my view component doesn't have its model populated. One thing I noticed I had done incorrectly is putting a route parameter at the top; e.g.,

@page "{handler?}"

I know (now at least) that View Components are not intended to be routed to directly as endpoints, but now I'm curious what does using a @page with a route attribute do to prevent the model binding from happening? I only discovered by trial/error that removing this lets my model get populated within the View Component.

Here is the code

ViewComponent

public class TestViewComponent : ViewComponent
{

    public async Task<IViewComponentResult> InvokeAsync(Data.CustomerListModel cust)
    {
        List<Data.CustomerListModel> clist = new List<Data.CustomerListModel>();
        clist.Add(new Data.CustomerListModel() { Customer = "fred" });
        clist.Add(new Data.CustomerListModel() { Customer = "wilma" });

        var dlist = clist.AsEnumerable();

        return View(dlist);
    }
}

View for ViewComponent, Default.html

@page "{handler?}"
@using System.Collections.Generic
@addTagHelper *, TelerikAspnetCoreApp1
@model IEnumerable<Data.CustomerListModel>

<h1>Default</h1>

<h3>Machine name @Environment.MachineName</h3>
<ul>
    @foreach (Data.CustomerListModel c in Model)
    {
        <li>@c.Customer</li>
    }
</ul>

CustomerListModel

namespace TelerikAspNetCoreApp1.Data
{
    public class CustomerListModel
    {
        public string Customer { get; set; }
    }
}

Parent view, Index.cshtml

<div>
    @await Component.InvokeAsync("Test",new { Name = "tester123" })
</div>

Solution

  • The view of ViewComponent looks a lot like a Razor view file used in an ASP.NET Core app with controllers and views. Then @page directive is used in Razor page and it makes the file into an MVC action - which means that it handles requests directly, without going through a controller. @page affects the behavior of other Razor constructs.

    You could take aside time to read the MS documentations on the View Component and Razor Pages :

    https://learn.microsoft.com/en-us/aspnet/core/mvc/views/view-components?view=aspnetcore-3.0

    https://learn.microsoft.com/en-us/aspnet/core/razor-pages/?view=aspnetcore-3.0&tabs=visual-studio