How do I have to change the controller code (below) to allow viewmodel view to display? I know the action method needs to point to the AB model, but I don't know how to change the syntax to do this.
Models appear in the context file. My understanding is the viewmodels do not appear in the context. Am I correct?
Environment: Net Core 6 MVC, Visual Studio Community 2022 (64 bit), WIndows 11
GitHub: View Model Project
Please: whenever possible, provide help in the form of actual code - preferably changes to the code I've provided (a fair amount of time and effort goes into providing this code as the premise for the question) - or in example(s) of code you provide, in either case in the format / syntax the code needs to be in. Abstraction obfuscates the answer.
Models
A
namespace ViewModel.Models
{
public class A
{
public int Id { get; set; }
public string? One { get; set; }
public string? Two { get; set; }
public string? Three { get; set; }
public IEnumerable<C>? C { get; set; } <- IEnumerable
}
}
B
namespace ViewModel.Models
{
public class B
{
public int Id { get; set; }
public string? One { get; set; }
public string? Two { get; set; }
public string? Three { get; set; }
public IEnumerable<C>? C { get; set; } <- IEnumerable
}
}
C
using System.Security.Cryptography.Xml;
namespace ViewModel.Models
{
public class C
{
public int Id { get; set; }
public int AId { get; set; }
public int BId { get; set; }
// _______________________________________
public A? A { get; set; }
public B? B { get; set; }
}
}
ViewModel (Project.Models.View.AB)
using System.Security.Cryptography.Xml;
namespace ViewModel.Models.View
{
public class AB
{
public A? A { get; set; }
public B? B { get; set; }
}
}
View
@model IEnumerable<ViewModel.Models.View.AB> <- IEnumerable
@{
ViewData["AB"] = "AB";
}
<h1>AB</h1>
<p>
<a asp-action="Create">Create New</a>
</p>
<table class="table">
<thead>
<tr>
<th>
@Html.DisplayNameFor(model => model.A.One)
</th>
<th>
@Html.DisplayNameFor(model => model.B.Two)
</th>
<th></th>
</tr>
</thead>
<tbody>
@foreach (var item in Model) {
<tr>
<td>
@Html.DisplayFor(modelItem => item.A.One)
</td>
<td>
@Html.DisplayFor(modelItem => item.B.Two)
</td>
<td>
<a asp-action="Edit" asp-route-id="@item.A.Id">Edit</a> |
<a asp-action="Details" asp-route-id="@item.A.Id">Details</a> |
<a asp-action="Delete" asp-route-id="@item.A.Id">Delete</a>
</td>
</tr>
}
</tbody>
</table>
Controller
// GET: AB
public async Task<IActionResult> AB()
{
return _context.A != null ?
View(await _context.A.ToListAsync()) :
Problem("Entity set 'ViewModelContext.A' is null.");
}
Project builds successfully
**
Error when Run**
InvalidOperationException: The model item passed into the ViewDataDictionary is of type 'System.Collections.Generic.List1[ViewModel.Models.A]', but this ViewDataDictionary instance requires a model item of type 'System.Collections.Generic.IEnumerable
1[ViewModel.Models.View.AB]'.
Re: IEnumerable - the two models navigation properties are IEnumerable
public IEnumerable<C>? C { get; set; }
and the view is IEnumberable
@model IEnumerable<ViewModel.Models.View.AB>
Question
How do I have to change the controller code syntax (above) to allow viewmodel view to display?
Attempted Change 1
The controller action method below needs to point to the AB viewmodel. Changing A to AB in the current context not successful.
**
Changing _context.A to _context.AB**
// GET: AB
public async Task<IActionResult> AB()
{
return _context.AB != null ?
View(await _context.AB.ToListAsync()) :
Problem("Entity set 'ViewModelContext.A' is null.");
}
Error
CS1061 'ViewModelContext' does not contain a definition for 'AB' and no accessible extension method 'AB' accepting a first argument of type 'ViewModelContext' could be found (are you missing a using directive or an assembly reference?) ViewModel C:\Users\User1\Desktop_Tech\Net\ViewModel\ViewModel\ViewModel\Controllers\AController.cs 33 Active
Question:
Models appear in the context file. My understanding is the viewmodels do not appear in the context. Am I wrong?