我试图在一个视图中使用两个模型,但据我所知,我的程序只是在模型中看不到任何对象。
这是我的代码。
型号:
public class Album
{
[Key]
public int ThreadId { get; set; }
public int GenreId { get; set; }
public string Title { get; set; }
public string ThreadByUser { get; set; }
public string ThreadCreationDate { get; set; }
public string ThreadContent { get; set; }
public Genre Genre { get; set; }
public List<Posts> Posty { get; set; }
}
public class Posts
{
[Key]
public int PostId { get; set; }
public int ThreadId { get; set; }
public string PostTitle { get; set; }
public string PostContent { get; set; }
public string PostDate { get; set; }
public string PosterName { get; set; }
public Album Album { get; set; }
}
public class ModelMix
{
public IEnumerable<Posts> PostsObject { get; set; }
public IEnumerable<Album> ThreadsObject { get; set; }
}
索引控制器代码:
public ActionResult Index(int id)
{
ViewBag.ThreadId = id;
var posts = db.Posts.Include(p => p.Album).ToList();
var albums = db.Albums.Include(a => a.Genre).ToList();
var mixmodel = new ModelMix
{
PostsObject = posts,
ThreadsObject = albums
};
return View(mixmodel);
}
查看代码:
@model MvcMusicStore.Models.ModelMix
<h2>Index</h2>
@Html.DisplayNameFor(model => model.PostsObject.PostContent)
当我尝试执行我的程序时,我收到此错误:
CS1061:“ System.Collections.Generic.IEnumerable'不包含定义 “PostContent”没有找到扩展“PostContent”的方法,其中 采用类型为'System.Collections.Generic.IEnumerable的第一个参数 “
如何让它按预期工作?我的网上有很多像我这样的问题,但是找不到符合我的情况。
答案 0 :(得分:7)
在MVC中循环模型可能有点混乱,只是因为模板化帮助器(即Html.DisplayFor
和Html.EditorFor
)可以提供模板,帮助程序将自动为每个元素调用一个集合。这意味着如果您是MVC的新手,并且您没有意识到该集合尚未提供DisplayTemplate
或EditorTemplate
,则看起来很简单:
@Html.DisplayFor(m => m.SomePropertyThatHoldsACollection)
就是你所需要的。因此,如果您已经看过类似的东西,这可能就是您做出假设的原因。但是,让我们暂时假设还没有提供模板。你有两个选择。
首先,最简单的说就是在集合上使用foreach
:
@foreach (var post in Model.PostsObject)
{
@Html.DisplayFor(m => post.PostTitle)
// display other properties
}
您也可以使用for
循环,但使用IEnumerable<T>
时,没有索引器,所以这不起作用:
@for (int i = 0; i < Model.PostsObject.Count(); i++)
{
// This generates a compile-time error because
// the index post[i] does not exist.
// This syntax would work for a List<T> though.
@Html.DisplayFor(m => post[i].PostTitle)
// display other properties
}
如果你确实想要使用for
循环,你可以这样使用它:
@for (int i = 0; i < Model.PostsObject.Count(); i++)
{
// This works correctly
@Html.DisplayFor(m => post.ElementAt(i).PostTitle)
// display other properties
}
所以请根据自己的喜好使用。但是,在某些时候,考虑提供templates for your types是个好主意。 (注意:尽管本文是针对MVC 2编写的,但该建议仍然适用。)它们允许您从视图中删除循环逻辑,使其更清晰。与Html.DisplayFor
或Html.EditorFor
结合使用时,它们还会为模型绑定生成正确的元素命名(这很棒)。它们还允许您重用类型的演示文稿。
我要做的最后一个评论是你的属性的命名有点冗长:
public class ModelMix
{
public IEnumerable<Posts> PostsObject { get; set; }
public IEnumerable<Album> ThreadsObject { get; set; }
}
我们已经知道它们是对象,所以最后不需要添加它。这更具可读性:
public class ModelMix
{
public IEnumerable<Posts> Posts { get; set; }
public IEnumerable<Album> Threads { get; set; }
}
答案 1 :(得分:0)
你需要像这样迭代它们:
@model MvcMusicStore.Models.ModelMix
<h2>Index</h2>
@for(var i=0; i<model.PostsObject.Count(); i++)
{
@Html.DisplayNameFor(model => model.PostsObject[i].PostContent)
}
并且最好保存IList而不是IEnumerable,因为它将具有Count属性,而不是使用Count()方法
答案 2 :(得分:0)
如果您传入任何类型的IEnumerable<>
,通常需要遍历每个项目。由于您构建了一个半复杂模型,因此您需要在每个列表中显示foreach
项。这是一个基于ASP.NET MVC教程的示例,我认为这对您有所帮助:
@model IEnumerable<ContosoUniversity.Models.Course>
@{
ViewBag.Title = "Courses";
}
<h2>Courses</h2>
<p>
@Html.ActionLink("Create New", "Create")
</p>
<table class="table">
<tr>
<th>
@Html.DisplayNameFor(model => model.CourseID)
</th>
<th>
@Html.DisplayNameFor(model => model.Title)
</th>
<th>
@Html.DisplayNameFor(model => model.Credits)
</th>
<th>
Department
</th>
<th></th>
</tr>
@foreach (var item in Model) {
<tr>
<td>
@Html.DisplayFor(modelItem => item.CourseID)
</td>
<td>
@Html.DisplayFor(modelItem => item.Title)
</td>
<td>
@Html.DisplayFor(modelItem => item.Credits)
</td>
<td>
@Html.DisplayFor(modelItem => item.Department.Name)
</td>
<td>
@Html.ActionLink("Edit", "Edit", new { id=item.CourseID }) |
@Html.ActionLink("Details", "Details", new { id=item.CourseID }) |
@Html.ActionLink("Delete", "Delete", new { id=item.CourseID })
</td>
</tr>
}
</table>
通常大多数人会为其列表使用ICollection
,其中示例可能位于对象中:
public virtual ICollection<Post> Posts { get; set; }
我建议从头开始,因为它会帮助您理解为什么需要这样做: http://www.asp.net/mvc/tutorials/getting-started-with-ef-using-mvc