Share via


Passing IEnumerable Model with ViewData.

Question

Tuesday, May 21, 2013 3:14 AM

Controller

var listmodel = db.Letters.Where(r => r.ThreadId == id)

.OrderBy(r => r.Date);

ViewData["ListModel"] = listmodel;

View

@Html.Partial("_CreateLetter",ViewData["ListModel"])

**
**

Error

The model item passed into the dictionary is of type 'System.Data.Entity.Infrastructure.DbQuery`1[LetterManager.Models.Letter]', but this dictionary requires a model item of type 'LetterManager.Models.Letter

PartialView

@model IEnumerable<LetterManager.Models.Letter>

All replies (15)

Tuesday, May 21, 2013 8:29 AM âś…Answered

Hello,
While calling your partials view do following.
@Html.Partial("_CreateLetter",ViewData["ListModel"] as System.Collections.IEnumerable())

This will work.


Tuesday, May 21, 2013 3:18 AM

Try following:

var listmodel = (db.Letters.Where(r => r.ThreadId == id)

.OrderBy(r => r.Date)).ToList();

ViewData["ListModel"] = listmodel;


Tuesday, May 21, 2013 3:27 AM

Already Tried this..

It Gives 

The model item passed into the dictionary is of type 'System.String', but this dictionary requires a model item of type 'LetterManager.Models.Letter'.

Error


Tuesday, May 21, 2013 3:35 AM

that's because your Partial model , is of type LetterManager.Models.Letter

but you pass a List of Letter.

change your code this way:

var listmodel = db.Letters.Where(r => r.ThreadId == id)

.OrderBy(r => r.Date).Single();

or change type of partial view to IEnumerable<Letter> instead of**  LetterManager.Models.Letter**


Tuesday, May 21, 2013 3:49 AM

alishokr.. Not a correct option

Single(); i am Trying to Show a list of letters.

LetterManager.Models.Letter i already have

@model IEnumerable<LetterManager.Models.Letter> ,  IEnumerable<Letter> Are equivalent 

in order to use  IEnumerable<Letter> i have to add a Using LetterManager.Models.. None of these make any difference 

**
**


Tuesday, May 21, 2013 3:58 AM

The model item passed into the dictionary is of type 'System.Data.Entity.Infrastructure.DbQuery`1[LetterManager.Models.Letter]', but this dictionary requires a model item of type 'LetterManager.Models.Letter

the error you provided says that your partial model is of type Letter instead of IEnumerable<Letter>

it sounds wierd, but did you try to cast ViewData["ListModel"] to IEnumerable<Letter> when you are passing it to Partial ?


Tuesday, May 21, 2013 4:01 AM

Haven't Done Anything.. have no Idea why this error is Falling

Full View

@model IEnumerable<LetterManager.Models.Letter>

<p>
@Html.ActionLink("Create New", "Create")
</p>
<table>
<tr>
<th>
@Html.DisplayNameFor(model => model.Date)
</th>
<th>
@Html.DisplayNameFor(model => model.RefNo)
</th>
<th>
@Html.DisplayNameFor(model => model.Author)
</th>
<th>
@Html.DisplayNameFor(model => model.DespatchOffice)
</th>
<th>
@Html.DisplayNameFor(model => model.Subject)
</th>
<th>
@Html.DisplayNameFor(model => model.File_Url)
</th>
<th>
@Html.DisplayNameFor(model => model.ThreadId)
</th>
<th></th>
</tr>

@foreach (var item in Model) {
<tr>
<td>
@Html.DisplayFor(modelItem => item.Date)
</td>
<td>
@Html.DisplayFor(modelItem => item.RefNo)
</td>
<td>
@Html.DisplayFor(modelItem => item.Author)
</td>
<td>
@Html.DisplayFor(modelItem => item.DespatchOffice)
</td>
<td>
@Html.DisplayFor(modelItem => item.Subject)
</td>
<td>
@Html.DisplayFor(modelItem => item.File_Url)
</td>
<td>
@Html.DisplayFor(modelItem => item.ThreadId)
</td>
<td>
@Html.ActionLink("Edit", "Edit", new { id=item.Id }) |
@Html.ActionLink("Details", "Details", new { id=item.Id }) |
@Html.ActionLink("Delete", "Delete", new { id=item.Id })
</td>
</tr>
}

</table>


Tuesday, May 21, 2013 4:06 AM

This below code will works for you

 List<Letters> viewModelList = new List<Letters>();
        viewModelList = db.Letters.Where(r => r.ThreadId == id).toList();
        return View(viewModelList);


Tuesday, May 21, 2013 4:16 AM

Hi 

@model IEnumerable<LetterManager.Models.Letter>

As you are using IEnumerable in view as Model, you need to cast list from your controller like below.

@Html.Partial("_CreateLetter",ViewData["ListModel"].AsEnumerable())

Tuesday, May 21, 2013 5:07 AM

Sunny Jagtap

Error

The model item passed into the dictionary is of type 'System.Collections.Generic.List`1[LetterManager.Models.Letter]', but this dictionary requires a model item of type 'LetterManager.Models.Letter'.

List<Letter> viewModelList = new List<Letter>();

viewModelList = db.Letters.Where(r => r.ThreadId == id).ToList()

ViewData["ListModel"] = viewModelList; 

I have to pass it with ViewData Because i am Already passing a model for the view..

Letter Model is for partialview


Tuesday, May 21, 2013 7:26 AM

Hello Shanker

@model IEnumerable<LetterManager.Models.Letter> Tells me you have a strongle typed view, i.e. the view is strongly bound to the model IEnumerable<LetterManager.Models.Letter>. What I get from your code is that you need to pass the model to the partial view differently. You explicitly use ViewData, but you need to just pass an instance of the model to the view as a parameter of the Partial method:

Controller method:

var listmodel = db.Letters.Where(r => r.ThreadId == id)
.OrderBy(r => r.Date)
.AsEnumerable();

In the view:

@Html.Partial("_CreateLetter", listmodel);

 

 


Tuesday, May 21, 2013 8:36 AM

The ViewData["ListModel"] construct implies you are using a dynamic typed view, but the @model IEnumerable<LetterManager.Models.Letter> construct in your view implies a strong typed view. This seems to create confusion and buggy code.

Which type of view are are you trying to implement? strong or dynamic?


Tuesday, May 21, 2013 11:50 AM

Strong.. 

Letter is A Strongly typed Model for this Perticular Partial View.

I ended up doing this..

@foreach (var item in Model.Letters)
{

<b>@Html.DisplayFor(modelItem => item.Date)</b>

<text>, Ref.No: </text><b> @Html.DisplayFor(modelItem => item.RefNo)</b> <br />

<text>Author : </text>@Html.DisplayFor(modelItem => item.Author)

<text>, Despatch Office : </text>@Html.DisplayFor(modelItem => item.DespatchOffice)<br />

<text>Subject : </text>@Html.DisplayFor(modelItem => item.Subject)<br />

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

@Html.ActionLink("Delete", "Delete", new { id=item.Id })
<hr />

}

As My Model for the detail view is thread and thread have Icollection<Letter> so i get to them through this method...


Tuesday, May 21, 2013 12:01 PM

Sunny Jagtap  you'r right..

This Worked Like a Cream too. 

@Html.Partial("_ListViewLetter",ViewData["ListView"] as IEnumerable<LetterManager.Models.Letter>)


Wednesday, May 22, 2013 5:20 AM

Hello Shanker,

While that makes the code work, I'd still like to challenge the solution. IMHO - It's semantically incorrect.

ViewData contains the Model property which is used for passing the model object instance from controller to view. It get's assigned by the MVC framework. You should then use the Model property in your view to access that model.

In the solution proposed by Sunny, the ViewData in the view gets passed two references to the model:

  1. ViewData["ListView"]
  2. ViewData.Model

 

If you don't fill the ViewData dictionary, but pass the model instance directly as an IEnumerable<LetterManager.Models.Letter>). Then the ViewData dictionary stays empty to the view and only the ViewData.Model property will have a reference to your model data (and you still use the Model property in your view)

Documentation references:
ViewDataDictionary.Model Property http://msdn.microsoft.com/en-us/library/system.web.mvc.viewdatadictionary.model.aspx

ViewPage.Model Property http://msdn.microsoft.com/en-us/library/system.web.mvc.viewpage.model.aspx
Building a Strongly-Typed View (article) http://www.howmvcworks.net/OnViews/BuildingAStronglyTypedView (specifically "Handing the Model to the View")

Just my 2 cts.

Regards,