GeorgiG GeorgiG - 2 months ago 30
C# Question

Trying to use two models in a view. Composite model does not contain extension method

I know there are a lot of topics about this issue, but none answers this specific problem of mine. I have a MVC project in which I want to implement two models on one View (separate tables).

I used the validated suggestion from the link to execute just that:
How do I view the parent view model MVC3 C#?

Here's my code:

-First model

[Table("Issue_Tracker")]
public class Case
{...
}


-Second model:

[Table("Jobs_Ref_Tbl")]
public class Job
{...
}


-Composite model:

public class IndexPageModel
{
public IEnumerable<Case> Cases { get; set; }
public IEnumerable<Job> Jobs { get; set; }
}


-Creating my CaseDBContext:

public class CaseDBContext : DbContext
{
public DbSet<Case> Cases { get; set; }
public DbSet<Job> Jobs { get; set; }
public DbSet<Server> Servers { get; set; }
public DbSet<User> Users { get; set; }
public DbSet<Department> Departments { get; set; }
}


In the controller I have sorted and filtered version of Cases model, using LINQ queries. After all the sorting and filtering, I used to pass an IPagedList of cases model to the view.

Now I have:

var cases = db.Cases.AsQueryable();
[sorts and filters]
var model = new IndexPageModel
{
Jobs = db.Jobs.ToPagedList(page ?? 1, 5),
Cases = cases.ToPagedList(page ?? 1, 10)
};
return View(model);


And finally I use them in the View:

<!DOCTYPE html>
@using PagedList;
@using PagedList.Mvc;
@model IPagedList<ITS.Models.IndexPageModel>
...
<table id="tableBe">
<tr>
<th style="border-left:none !important">
Action Buttons
</th>
<th>
<div style="width: 250px">
@Html.DisplayNameFor(model => model.Cases.First().Issue)


And here I run into the problem


'IPagedList' does not contain a definition for 'Cases' and no extension method 'Cases' accepting a first argument of type 'IPagedList' could be found (are you missing a using directive or an assembly reference?)


It's as if I did not include them in the model at all. Any advice on how to solve this problem would be appreciated.

EDIT: ADDITIONAL INFO

The code is very long, there are many filters in order to support combined search function. The basics consist of the 5th code snippet in my post:

I declare my IQueryable then manipulate it and after that I insert it into the model as the cases variable. db.Jobs I leave intact and thats why I insert it directly into the model variable.

It used to be:

var cases = db.Cases.AsQueryable();
[sorts and filters]
return View(cases.ToPagedList(page ?? 1, 10));


I want it to be:

var cases = db.Cases.AsQueryable();
[sorts and filters]
var model = new IndexPageModel
{
Jobs = db.Jobs.ToList()
Cases = cases
};
return View(model.ToPagedList(page ?? 1, 10));


But it returns


'IndexPageModel' does not contain a definiton for 'ToPagedList'

Answer

Your controller is returning a IndexPageModel, but your view wants a IPagedList<ITS.Models.IndexPageModel>. Change your model to accept the correct model:

<!DOCTYPE html>
@using PagedList;
@using PagedList.Mvc;
@model ITS.Models.IndexPageModel // The correct model.

Based on model => model.Cases.First().Issue it seems that you actually want to use the model returned from the controller (IndexPageModel).

I assume ToPagedList() returns an IPagedList<T>. Which means that you actually just want to use IPagedList in the IndexPageModel, but not in the actual view. So based on that you should be able to simply change the model in the view and it will work.

Comments