Is there a way to add something like a PageModel to a partial view. i want to have a dropdown that shows my active projects like so:
<li >
<a href="#" id="navbardrop" data-toggle="dropdown">
Projects
</a>
<div >
@foreach(var p in Model.UserProjects)
{
<a asp-area="" asp-page="/Category Display/Index" asp-route-projectId="@p.Id">@p.productName</a>
}
</div>
</li>
But _Layout.cshtml
lacks a model or something similar.
Trying to add my class:
public class LayoutModel : PageModel
{
private readonly ApplicationDbContext _db;
public List<UserProject> UserProjects { get; set; }
public LayoutModel(ApplicationDbContext db)
{
_db = db;
}
public async Task OnGet(int categoryId)
{
UserProjects = await _db.UserProject.ToListAsync();
}
}
By adding @model LayoutModel
to the top of the layout file results in an error:
InvalidOperationException: The model item passed into the ViewDataDictionary is of type 'Scratch.Pages.IndexModel', but this ViewDataDictionary instance requires a model item of type 'Scratch.Pages.Shared.LayoutModel'.
How do I go about this?
CodePudding user response:
I think you can use View Component to achieve it. Please refer to this simple demo:
Create a component class:
public class ShowViewComponent : ViewComponent
{
//you can inject db into view component
private readonly ApplicationDbContext _db;
public List<UserProject> UserProjects { get; set; }
public ShowViewComponent(ApplicationDbContext db)
{
_db = db;
}
public IViewComponentResult Invoke()
{
//UserProjects = await _db.UserProject.ToListAsync();
//return View(UserProjects );
//for testing, I just hard code here.
List<string> list = new List<string>();
list.Add("AAA");
list.Add("BBB");
list.Add("ccc");
return View(list);
}
}
Then you need to create a component view, Please note that the path of component view should be :
Pages\Shared\Components\{your view component's name}\Default.cshtml
So here my path is :
Pages\Shared\Components\Show\Default.cshtml
View
@model List<string>
<table >
@foreach (var item in Model)
{
<h1>@item</h1>
}
</table>
Finally, I need to use this view component in _Layout.cshtml
:
<div>
@await Component.InvokeAsync("Show");
</div>
Demo: