I keep getting this error for my project.
The model item passed into the dictionary is of type
'System.Collections.Generic.List1[<>f__AnonymousType2
2[System.String,System.String]]',
but this dictionary requires a model item of type
'System.Collections.Generic.IEnumerable`1[ETMS.Models.DB.tblParent]'.
Description: An unhandled exception occurred during the execution of
the current web request. Please review the stack trace for more
information about the error and where it originated in the code.
==================================================================================
What i want to do is to retrieve the data from the database (one to many) , This is my database table structure
tblparent
- Parent_ID
- Username
- Password
- Firstname
- Lastname
and
tblParentEmail
- ParentEmail_ID
- Email
- Parent_ID
i was made the foreign relation from email to parent, but i could not include with EF while there is another error. i do in this way and caused me this error :
public ActionResult Clientlist()
{
using (ETMSPeopleEntities db = new ETMSPeopleEntities())
{
//var sxc = db.tblParents.Include("tblLocation").Include("tblParentEmails.ParentEmail_ID")
// .OrderByDescending(p => p.Status).ToList();
var members = (from x in db.tblParentEmails
join y in db.tblParents
on x.Parent_ID equals y.Parent_ID
select new { Email = x.ParentEmail, UserName = y.Username }).AsEnumerable();
return View(members.ToList());
}
}
This is my admincontroller
@model IEnumerable<ETMS.Models.DB.tblParent>
@{
ViewBag.Title = "Clientlist";
}
<h2>Clientlist</h2>
<p>
@Html.ActionLink("Create New", "Create")
</p>
<table>
<tr>
<th>
Username
</th>
<th></th>
</tr>
@foreach (var item in Model) {
<tr>
<td>
@Html.DisplayFor(modelItem => item.Username)
</td>
<td>
@Html.DisplayFor(modelItem => item.Firstname)
</td>
<td>
@Html.DisplayFor(modelItem => item.Lastname)
</td>
<td>
@Html.DisplayFor(modelItem => item.Location_ID)
</td>
<td>
@Html.DisplayFor(modelItem => item.Email)
</td>
<td>
@Html.DisplayFor(modelItem => item.CreateTime)
</td>
<td>
@Html.ActionLink("Edit", "Edit", new { id=item.Parent_ID }) |
@Html.ActionLink("Details", "Details", new { id=item.Parent_ID }) |
@Html.ActionLink("Delete", "Delete", new { id=item.Parent_ID })
</td>
</tr>
}
</table>
this is clientlist view
You're passing a list of anonymous objects to your view:
select new { Email = x.ParentEmail, UserName = y.Username }
While the view is expecting IEnumerable<ETMS.Models.DB.tblParent>
:
@model IEnumerable<ETMS.Models.DB.tblParent>
You should change your selection to:
select y
in order for the code to work.
Update
Here is how you could use a view model pattern. First, create a view model class, so you're not passing an anonymous type to your view. Let's call it AwesomeEmailViewModel
, and it looks like you need .Email
, .Username
and some other properties, so we'll set those up too.
public class AwesomeEmailViewModel
{
public string Email { get; set; }
public string Username { get; set; }
public string FirstName{ get; set; }
public string LastName { get; set; }
public int Location_ID{ get; set; }
public DateTime CreateTime { get; set; }
}
Now, modify your query by using object initialization to populate an instance of AwesomeEmailViewModel
Note: I am guessing which properties belong to which objects (either tblParent or tblParentEmails, so you will need to double-check these
var members = (from x in db.tblParentEmails
join y in db.tblParents
on x.Parent_ID equals y.Parent_ID
select new AwesomeEmailViewModel()
{
Email = x.ParentEmail,
UserName = y.Username,
FirstName = y.FirstName,
LastName = y.LastName,
Location_ID = x.Location_ID,
CreateTime = y.CreateTime,
}).ToList();
// I don't know if you'll need the `AsEnumerable()` call
return View(members);
Finally, your view has to know what type(s) to expect, so let's modify it to expect a list of our newly created AwesomeEmailViewModel instances.
@model IEnumerable<ETMS.Models.AwesomeEmailViewModel>
Pay close attention, as I guessed at the namespace as well. In any case, this should give you access to the properties you need inside your view. If you need more, you'll need to modify the new view model class we created as well as the query in your controller action.
Your view expects tblParent but you are passing it the joined table.
You need to create a ViewModel, join your tables there and change your view to expect the ViewModel rather than tblParent.
Thre are loads of examples. Here's one: ASP.NET MVC ViewModel Pattern
I hope this helps
Davy
In the view file, you require a model of type IEnumerable of ETMS.Models.DB.tblParent, and in the controller, you pass in members.ToList(), you have to change either one to make it match.
You can create a viewmodel like this
public Class Client
{
public string Email {get;set;}
public string UserName {get;set;}
}
And return a list of this instead of anonymous type in your controller action, and you will define IEnumerable of Client type in your view.
Your returning an anonymous type from your linq query. Your view is expecting a list of type tblParent
Project your linq into the correct type and it should be fine.
At a glance it looks like
select new { Email = x.ParentEmail, UserName = y.Username })
should be
select y
That's because you did a "select new" which creates a new anonymous type. The view is expecting tblParent. Anonymous types cannot be cast to a concrete type by the view engine. To fix, either return tblParent from your LINQ query or change your model to "@model dynamic".