Answered by:
this ViewDataDictionary instance requires a model item of type 'System.Collections.Generic.IEnumerable Error

Question
-
User1554758465 posted
I got this error multiple times, and i tried to understand what is exactly wrong but unfortunately i couldn't. So , Any help in this is much appreciated.
Error:
InvalidOperationException: The model item passed into the ViewDataDictionary is of type 'TestApplication.Models.Approval', but this ViewDataDictionary instance requires a model item of type 'System.Collections.Generic.IEnumerable`1[TestApplication.Models.ViewModels.RequestApprovalViewModel]'.
I have 2 models (Requests) & (Approvals). one request could have many approvals.
Here is My Models.
public class Request { public int Id { get; set; } public string Type { get; set; } public DateTime Date { get; set; } public int Seats { get; set; } public bool isDone { get; set; } public string InstitutionId { get; set; } [ForeignKey("InstitutionId")] public virtual Institution Institution { get; set; } //public virtual ICollection<Approval> Approvals { get; set; } } public class Approval { public int Id { get; set; } public string Status { get; set; } public DateTime Date { get; set; } public int RequestId { get; set; } public string ManagerId { get; set; } [ForeignKey("RequestId")] public virtual Request Request { get; set; } [ForeignKey("ManagerId")] public virtual ApplicationUser Manager { get; set; } }
Here i have the View where i'm displaying all requests where (isDone == true). Next to each request i have button to display a table in a modal popup of this request history.
@model IEnumerable<Approval> @{ ViewData["Title"] = "Requests"; } <div class="border"> <div> @if (Model.Count() > 0) { <table class="table table-striped"> <tr class="table-secondary"> <th> Institution Name </th> <th> Approval Status </th> <th> Request History </th> </tr> @foreach (var item in Model) { <tr> <td> @Html.DisplayFor(m => item.Request.Institution.Name) </td> <td> @Html.DisplayFor(m => item.Status) </td> <td> <button type="submit" class="btn btn-success anchorDetail" data-target="#modal-@item.Request.Institution.AdminId" data-toggle="modal"> Show Details </button> </td> <td> <div class="modal fade" id="modal-@item.Request.Institution.AdminId" tabindex="-1" role="dialog" aria-hidden="true"> <div class="modal-dialog-centered modal-dialog" role="document"> <div class="modal-content"> <div class="modal-header bg-success text-light justify-content-center"> <h5 class="modal-title">Request Details</h5> </div> <div class="modal-body justify-content-center" id="MyModalContent"> @await Html.PartialAsync("_RequestHistory", item) </div> <div class="modal-footer"> <button type="button" class="btn btn-secondary" data-dismiss="modal">إغلاق</button> </div> </div> </div> </div> </td> </tr> } </table> } else { <p>No Requests Exists...</p> } </div> </div> @section scripts { <script>var PostBackURL = '/Request/History'; $(function () { $(".anchorDetail").click(function () { var $buttonClicked = $(this); var id = $buttonClicked.attr('data-id'); $.ajax({ type: "GET", url: PostBackURL, contentType: "application/json; charset=utf-8", data: { "Id": id }, cache: false, datatype: "json", success: function (data) { $('#MyModalContent').html(data); $('#myModal').modal('show'); }, error: function () { alert("Dynamic content load failed."); } }); })</script> } <div class="modal fade" id="MyModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel"> <div id='MyModalContent'></div> </div>
Here is my Controller
[Authorize(Roles = SD.ManagerUser)] public async Task<IActionResult> Requests() { var requests = await _db.Approval .Include(c => c.Request) .ThenInclude(c => c.Institution) .Where(c => c.Request.isDone == true) //should be true //.ThenInclude(c => c.Admin) .ToListAsync(); return View(requests); } public async Task<IActionResult> History() { RequestApprovalViewModel model = new RequestApprovalViewModel() { Approvals = await _db.Approval.ToListAsync(), request = new Request() }; return PartialView("_RequestHistory", model); } [HttpPost] [ValidateAntiForgeryToken] public async Task<IActionResult> History(RequestApprovalViewModel model) { var approvals = await _db.Approval .Include(c => c.Request) .Where(c => c.RequestId == model.request.Id).ToListAsync(); return PartialView("_RequestHistory", approvals); }
My RequestApprovalViewModel
public class RequestApprovalViewModel { public Request request { get; set; } public virtual ICollection<Approval> Approvals { get; set; } }
And Finally this is the partialView content
@model IEnumerable<TestApplication.Models.ViewModels.RequestApprovalViewModel> @{ ViewData["Title"] = "Requests"; } <table class="table table-bordered table-striped datatable" id="table-3" dir="rtl"> <thead> <tr> <th> Seat number </th> <th>Request Date </th> <th> Approval Status </th> <th> Approval Date </th> </tr> </thead> <tbody> @foreach (var item in Model) { <tr> <!-- Here where i should display a table of the approval history of the requst --> </tr> } </tbody> </table>
Friday, July 17, 2020 1:54 PM
Answers
-
User-17257777 posted
Hi ShahadAlshuhail,
ShahadAlshuhail
@await Html.PartialAsync("_RequestHistory", item)
The problem is clear. Here, the item you pass to the partial view is type of Approval , while the partial view accpet a type of
IEnumerable<TestApplication.Models.ViewModels.RequestApprovalViewModel>
You should change one of them to keep their types consistent.
Best Regards,
Jiadong Meng
- Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
Monday, July 20, 2020 9:02 AM