1
votes

I have an ASP.NET MVC 5 app where users can see an index of projects. I have added another database table called "Applications", which would store application objects that the users create when they apply for a project from the index. The Applications model:

public class Application
{
    public int ApplicationId { get; set; }
    public int ProjectId { get; set; }
    public string UserId { get; set; }
    public string CoverLetter { get; set; }

}

Where ProjectId and UserId are foreign keys (from dbo.Projects and dbo.AspNetUsers respectively)

Now for the Projects index view I have changed the view model into ApplicationTwoViewModel:

 public class ApplicationTwoViewModel
    {
        public IEnumerable<Project> Model1 { get; set; }
        public Application Model2 { get; set; }
    }

The Index.cshtml:

@using Leepio.Models
@using Microsoft.AspNet.Identity
@model ApplicationTwoViewModel

@{
    ViewBag.Title = "Index";
}

<h2>Index</h2>

<p>
    @Html.ActionLink("Create New", "Create" ,"Projects")
</p>
<table class="table">
    <tr>
        <th>
            @Html.ActionLink("Title", "Index", "Projects", new {SortOrder = (ViewBag.SortOrder==null?"Asc":(ViewBag.SortOrder=="Asc"?"Desc":"Asc")), SortBy = "Title"})

        </th>
        <th>
            @Html.ActionLink("Application Deadline", "Index", "Projects", new {SortOrder = (ViewBag.SortOrder == null ? "Asc" : (ViewBag.SortOrder == "Asc" ? "Desc" : "Asc")), SortBy = "ApplicationDeadline"}) <br/>
            @Html.ActionLink("Hourly Rate (DKK)", "Index", "Projects", new { SortOrder = (ViewBag.SortOrder == null ? "Asc" : (ViewBag.SortOrder == "Asc" ? "Desc" : "Asc")), SortBy = "HourlyRate" })
        </th>
       <th>
            @Html.ActionLink("Skill requirements", "Index", "Projects", new { SortOrder = (ViewBag.SortOrder == null ? "Asc" : (ViewBag.SortOrder == "Asc" ? "Desc" : "Asc")), SortBy = "RequiredSkills" })
        </th>


    </tr>

@foreach (var item in Model.Model1) {
    <tr>
        <td>
            @Html.DisplayFor(modelItem => item.Title)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.ApplicationDeadline)<br/>
            @Html.DisplayFor(modelItem => item.HourlyRate)
        </td>
       <td>
            @Html.DisplayFor(modelItem => item.RequiredSkills)
        </td>


        <td>

            @if(item.UserId == User.Identity.GetUserId()) 

            {
                @Html.ActionLink("Edit", "Edit", "Projects", new {id = item.ProjectId})

                @Html.ActionLink("Delete", "Delete", "Projects", new {id = item.ProjectId}) 
            }

            @Html.ActionLink("Details", "Details", "Projects", new {id = item.ProjectId}) |
            @Html.ActionLink("Apply", "Index", "Applications", new { id = item.ProjectId }) |
        </td>
    </tr>
}

</table>
@{
    double TotalPage = @ViewBag.TotalPages;
}

<ul class="pagination">
    @for (int i = 1; i <= TotalPage; i++)
    {

        if (i == ViewBag.Page)
        {
            <li class="active"> @Html.ActionLink(i.ToString() + " ", "Index", "Projects", new { SortOrder = (ViewBag.SortOrder == null ? "Asc" : ViewBag.SortOrder), SortBy = (ViewBag.SortBy == null ? "Title" : ViewBag.SortBy), Page = i })</li>
        }
        else
        {
            <li>
                @Html.ActionLink(i.ToString() + " ", "Index", "Projects", new { SortOrder = (ViewBag.SortOrder == null ? "Asc" : ViewBag.SortOrder), SortBy = (ViewBag.SortBy == null ? "Title" : ViewBag.SortBy), Page = i })
            </li>
        }

    }
</ul>

And of course I am using Model.Model1 and Model.Model2.

When trying to open the Projects index view I get the following: The model item passed into the dictionary is of type 'System.Collections.Generic.List`1[Leepio.Models.Project]', but this dictionary requires a model item of type 'Leepio.Models.ApplicationTwoViewModel'.

ProjectsController:

 public ActionResult Index(string SortOrder, string SortBy, string Page)
        {
            ViewBag.SortOrder = SortOrder;
            ViewBag.SortBy = SortBy;
            var projects = db.Projects.ToList();
            var model = new ApplicationTwoViewModel
            {
                Model1 = new List<Project>(projects),
                Model2 = new Application
                {

                    UserId = User.Identity.GetUserId(),
                    ProjectId = 11,
                    CoverLetter = "asdf",
                    ApplicationId = 23,
                }
            };

            //bunch of code I cut out regarding the sorting



        ViewBag.TotalPages =     Math.Ceiling(db.Projects.ToList().Count()/10.0);
        int page = int.Parse(Page == null ? "1" : Page);
        ViewBag.Page = page;
        projects = projects.Skip((page - 1) * 10).Take(10).ToList();
        return View(projects);

    }

I've tried initializing Model2 hard coded even though I do not want it this way. What could solve this error? I have a feeling the initialization is off but I am not sure

1
This would be downvoted as an answer, so as a comment: try return View(model);Tetsujin no Oni
you are return the wrong model to you view (return View(projects);). You need to return the var model = new ApplicationTwoViewModel to your view (return View(model);)zgood
In fact, this is so simple I'd call it a typo...Tetsujin no Oni
Actually it did fix the error thank you :) Sometimes other person can just see the issues in an instant when you were searching for it for an hour.crystyxn

1 Answers

4
votes

Your View expects you to accept an instace of your ApplicationTwoViewModel class as seen at the top of your Index.cshtml View:

@model ApplicationTwoViewModel

So you just need to create one and pass it in, which should be quite easy as you are already building it within your Controller Action :

// Pass the model to your View
return View(model);

Since you are explicitly editing it after initializing it, you'll probably want to perform the following before your return call and well as ensuring that any other operations (i.e. sorting and filtering) are done to the collection within your Model as well :

// Perform your paging at the model level
model.Model1 = model.Model1.Skip((page - 1) * 10).Take(10).ToList();
// Now return it
return View(model);