Reputation: 340
I have an ASP.NET Core MVC application using Razor and Entity Framework, and I try to include a (child) view in another one (parent).
A problem which I see is that they use different controllers. I obtained the child view following a Microsoft tutorial about using and integrating Entity Framework in a project.
When I try to start the application, it crashes because the model in the child view is null (see code below, simplified). To this stage, Notes controller -> Index action is not hit and I imagine this is because my code as it is now has nothing to point to Notes\Index. I don't know how to do that. I know including view in another even for different controllers is not a problem I am the first to confront with but all the solutions that I found don't seem to work with ASP.NET Core or maybe I using them wrong.
Child view (simplified):
..\ProgMain\Views\Notes\Index.cshtml
@model IEnumerable<ProgMain.Models.NoteRecord>
@{
ViewData["Title"] = "Index";
}
<h1>Index</h1>
<table class="table">
<thead>
<tr>
<th>
@Html.DisplayNameFor(model => model.Note)
</th>
<th></th>
</tr>
</thead>
<tbody>
@foreach (var item in Model) { // crash nullreferenceexception, Model is null
<tr>
<td>
@Html.DisplayFor(modelItem => item.Note)
etc.
Corresponding controller:
..\ProgMain\Controllers\NotesController.cs
namespace ProgMain.Controllers
{
public class NotesController : Controller
{
private readonly ApplicationDbContext _context;
public NotesController(ApplicationDbContext context)
{
_context = context;
}
public async Task<IActionResult> Index() // not hit
{
return _context.NotesSet != null
? View(await _context.NotesSet.ToListAsync())
: Problem("Entity set 'ApplicationDbContext.NotesSet' is null.");
}
etc
The Notes
model class:
..\ProgMain\Models\Notes.cs
namespace ProgMain.Models
{
public class NoteRecord
{
public Guid ID { get; set; }
public string? Note { get; set; }
public virtual List<NoteDetailRecord>? Details { get; set; }
}
etc.
}
The parent view:
..\ProgMain\Views\Home\Frontend.cshtml
@{
ViewData["Title"] = "Frontend"; // the upper entry in call stack, before crashed line
}
<div style="display:flex">
etc.
</div>
<partial name="/Views/Notes/Index.cshtml"></partial>
Upvotes: 1
Views: 164
Reputation: 1672
it crashes because the model in the child view is null (see code below, simplified).
In the code sample you provided, the problem is caused by the child view's model being null, because the child view is not receiving data from the parent view correctly, in ASP.NET Core, the model Tag Helper is used to specify the model passed to the detail view when using the label assistant,If the model property is not specified in the tag, the child view will not receive any model data.
To transfer the data to the partial view, you could use the model
attribute in the partial tag:
<partial name="/Views/Notes/Child.cshtml" model="Model" />
Updated:
Controllers/Homecontroller:
public class HomeController : Controller
{
private readonly ILogger<HomeController> _logger;
private readonly DropdownContext _context;
public HomeController(ILogger<HomeController> logger, DropdownContext context)
{
_logger = logger;
_context = context;
}
public async Task<IActionResult> Frontend()
{
var notesList = await _context.NotesSet.ToListAsync();
ViewData["NotesList"] = notesList;
return View();
}
}
Views/Home/Frontend.cshtml:
@{
ViewData["Title"] = "Frontend";
}
@{
var notesList = ViewData["NotesList"] as IEnumerable<Dropdowm.Models.NoteRecord>;
}
<div style="display:flex">
etc.
</div>
<partial name="/Views/Notes/Index.cshtml" model="@notesList" />
Controllers/NotesController:
public class NotesController : Controller
{
private readonly DropdownContext _context;
public NotesController(DropdownContext context)
{
_context = context;
}
public async Task<IActionResult> Index() // not hit
{
return _context.NotesSet != null
? View(await _context.NotesSet.ToListAsync())
: Problem("Entity set 'ApplicationDbContext.NotesSet' is null.");
}
}
Views/Notes/index.cshtml:
@model IEnumerable<Dropdowm.Models.NoteRecord>
@{
ViewData["Title"] = "Index";
}
@if (Model != null)
{
<table class="table">
<thead>
<tr>
<th>
@Html.DisplayNameFor(model => model.First().Note)
</th>
<th></th>
</tr>
</thead>
<tbody>
@foreach (var item in Model)
{
<tr>
<td>
@Html.DisplayFor(modelItem => item.Note)
</td>
</tr>
}
</tbody>
</table>
}
else
{
<p>No notes available.</p>
}
Upvotes: 2