Reputation: 6842
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>
Upvotes: 1
Views: 2838
Reputation: 1113
I just had a similar problem. I'm ashamed because it was a brutal rookie mistake. My mistake was that the objects I sent and received respectively were different. I my cshtml I had:
@if (Model is IHasBanner {HasMessage: true } model)
{
@await Component.InvokeAsync("MessageArea", model)
}
Then in my ViewComponent I had:
public async Task<IViewComponentResult> InvokeAsync(Banner banner)
=> this.View("Default", banner);
And in my View I had:
@if (Model is IHasBanner {HasMessage: true} model)
{
message = model.Banner.Text;
}
So the mess was perfect!
That's why you have to pay attention to which objects you work with during implementation! What is given, what is received. I was surprised that my Model was null within the View, but it was just a result of my own confusion.
Upvotes: 0
Reputation: 140
Don't use @page
in the page that you want to be executed by return View(<page_name>, <model>)
and the Model
property won't be null anymore.
Upvotes: 2
Reputation: 12685
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
Upvotes: 0