locked
Passing viewmodel to modal. With ICollection RRS feed

  • Question

  • User1554758465 posted

    I'm Starting developing my first web application following some tutorials in Asp.Net Core MVC .. And i'm enjoying it but since my experience is not that much it is challenging a little bit. I'm stucking here and i can not figure out what i'm doing wrong ?

    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>

    </div> </div>

    Friday, July 17, 2020 2:38 PM

Answers

  • User2078676645 posted

    Hi,

    ShahadAlshuhail

    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]'.

    Because the data you pass in the partial view in the requests view does not match the model required by the partial view.

    ShahadAlshuhail

    <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>

    ShahadAlshuhail

    @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>

    You need to change @model IEnumerable<TestApplication.Models.ViewModels.RequestApprovalViewModel> to @model TestApplication.Models.Approval.

    Best Regards,

    Evern

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Monday, July 20, 2020 5:24 AM