我在尝试渲染部分视图时遇到错误:
类型' System.InvalidOperationException'的例外情况发生在 System.Web.Mvc.dll但未在用户代码中处理
附加信息:传递到字典中的模型项是 类型 ' System.Data.Entity.DynamicProxies.Post_206B6491B2DC6BC95A9910F33BF20B9F1973E064A753CBEDF9E6C72F08A98532&#39 ;, 但是这个字典需要一个类型的模型项 ' System.Collections.Generic.IEnumerable`1 [MyBlogger.Post]'
PartialView:
IEnumerable<MyBlogger.Post>
@foreach (var item in Model) {
<p class="text-left">Similar Article: <a href="#">@Html.DisplayFor(modelItem => item.Title)</a></p>
}
MainDetails查看:
@model MyBlogger.Post
@{
ViewBag.Title = "MainDetails";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>@Html.DisplayFor(model => model.Title)</h2>
<header class="intro-header">
<div class="container">
<div class="row">
<div>
<div class="post-heading">
@*<a href="#">*@
<img class="img-responsive" src="~/Content/img/post-bg.jpg" alt="">
<h1>@Html.DisplayFor(model => model.ShortDescription)</h1>
<p class="text-left">Posted by <a href="#">@Html.DisplayFor(model => model.BlogUserEmail)</a> on @Html.DisplayFor(model => model.PostedOn)</p>
<p class="text-left">Category <a href="#">@Html.DisplayFor(model => model.Category.Name)</a></p>
@*</a>*@
</div>
</div>
</div>
</div>
</header>
<fieldset>
<div class="display-field">
@*@Html.DisplayFor(model => model.BlogUserEmail)*@
</div>
<div class="display-field">
@Html.Raw(HttpUtility.HtmlDecode(Model.Description))
</div>
<div class="display-field">
@Html.DisplayFor(model => model.Modified)
</div>
</fieldset>
@Html.Partial("SimilarPosts") // here
MainDetails行动:
public ActionResult MainDetails(string urlslug)
{
Post post = db.Posts.First(m => m.UrlSlug == urlslug);
if (post == null)
{
return HttpNotFound();
}
return View(post);
}
答案 0 :(得分:1)
正如其他人所说,这是你的模型结构导致你的问题。您将单个Post
对象发送到主视图,但您的子视图需要IEnumerable<Post>
。这里最好的解决方案是创建一个包含以下两者的视图模型:
public class PostViewModel
{
public Post CurrentPost { get; set; }
public IEnumerable<MyBlogger.Post> Posts { get; set; }
}
然后用以下内容填充:
public ActionResult MainDetails(string urlslug)
{
Post post = db.Posts.First(m => m.UrlSlug == urlslug);
List<Post> posts = db.Posts.ToList();
PostViewModel model = new PostViewModel
{
CurrentPost = post,
Posts = posts
};
if (post == null)
{
return HttpNotFound();
}
return View(model);
}
然后你的主要观点是:
@model PostViewModel
<h2>@Html.DisplayFor(model => model.CurrentPost.Title)</h2>
<header class="intro-header">
<div class="container">
<div class="row">
<div>
<div class="post-heading">
@*<a href="#">*@
<img class="img-responsive" src="~/Content/img/post-bg.jpg" alt="">
<h1>@Html.DisplayFor(model => model.CurrentPost.ShortDescription)</h1>
<p class="text-left">Posted by <a href="#">@Html.DisplayFor(model => model.CurrentPost.BlogUserEmail)</a> on @Html.DisplayFor(model => model.CurrentPost.PostedOn)</p>
<p class="text-left">Category <a href="#">@Html.DisplayFor(model => model.CurrentPost.Category.Name)</a></p>
@*</a>*@
</div>
</div>
</div>
</div>
</header>
<fieldset>
<div class="display-field">
@*@Html.DisplayFor(model => model.CurrentPost.BlogUserEmail)*@
</div>
<div class="display-field">
@Html.Raw(HttpUtility.HtmlDecode(Model.CurrentPost.Description))
</div>
<div class="display-field">
@Html.DisplayFor(model => model.CurrentPost.Modified)
</div>
</fieldset>
@Html.Partial("SimilarPosts", Model.Posts)
然后你的部分将是相同的:
@model IEnumerable<MyBlogger.Post>
@foreach (var item in Model) {
<p class="text-left">Similar Article: <a href="#">@Html.DisplayFor(modelItem => item.Title)</a></p>
}
答案 1 :(得分:1)
理想情况下,您需要创建一个viewmodel来保存视图的所有数据。 viewmodel是一个表示要在视图中显示的数据的类。如果您使用过Sql Server,您可以将其视为一个sql视图,在上下文中,它会将事物收集到一个可以在页面上使用的组中。
在您的情况下,您希望通过视图实现2个特定操作。
<强>视图模型强>
public class BlogDetailsViewModel{
public Blog SingleBlogItem { get; set; } // (0)
public IEnnumerable<Blog> SimilarBlogs { get; set; } // (1)
}
在该代码中,我们设置了viewmodel来保存视图所需的内容。它是该视图的模型。现在它只是设置为Blog (0)
和IEnumerable<Blog> (1)
对象的表示。类似的博客如何与单一博客项目相关?这是供您决定的。我将为本文的目的添加一个简单的解决方案。
BlogPostRelation(POCO类)
public class BlogPostRelation{
public int Id {get; set;}
public int BlogId {get; set;}
public int SimilarBlogId {get; set;}
}
因此,在此类中,表中的每一行都将通过博客项和相似的关联博客项进行连接。当您保存具有类似博客的博客项目时,您还可以使用主BlogId (0)和SimilarBlogId (1)添加到此表中。因此,如果您保存4个类似的博客,则此表中将有4行保存的博客BlogId
。
<强>控制器强>
public ActionResult BlogDetails(int blogId){
// First find the blog you want. We assign it here instead of in the
// new BlogDetailViewModel so that we can use it as a condition on
// the similiar blogs
Blog blog = context.Blog.firstOrDefault(b => b.BlogId == blogId);
BlogDetailViewModel model = new BlogDetailViewModel{
SingleBlogItem = blog,
SimilarBlogs = context.BlogPostRelation.Where(b => b.BlogId == blog.BlogId).ToList()
}
// Now pass this viewmodel to the main view
return View(model)
}
您现在有一个模型(您可能想要添加条件,如果找不到),您可以在视图和局部视图中使用它,记住视图的规范是{ {1}}和Blog (0)
。现在,视频模型中包含IEnumerable<Blog> (1)
和SingleBlogItem (0)
查看强>
SimilarBlogs (1)
因此,在主视图中,您可以像往常一样通过向模型添加@model PATH.TO.VIEWMODEL.BlogDetailViewModel
@Html.DisplayFor(model => model.SingleBlogItem.Modified)
的前缀来分配模型(它是强类型的,因此会有intellesense)。然后是部分视图
调用partialview
SingleBlogItem (0)
在这里,您将视频模型中存在的类似帖子@Html.Partial("SimilarPosts",Model.SimilarBlogs)
传递给部分视图
<强> PartialView 强>
Model.SimilarBlogs (1)
最后,您将Blog对象称为IEnumerable,对于该partialview的模型没有错误,因为此partialview需要@model IEnumerable<Blog>
@foreach (var item in Model) {
<p class="text-left">Similar Article:
<a href="#">@Html.DisplayFor(modelItem => item.Title)</a></p>
}
并且在通过该模型时从主视图中获取IEnumerable<Blog>
进入部分视图
最好记住,当显示视图时,视图需要显示的所有内容都打包在模型中,这是应该在控制器中完成的工作。
我知道我已将其创建为博客,而不是基于您问题中的实际模型。我只是不想在你创建的内容和解决方案的简单描述之间混淆。我认为将相对于类似的博客描述为一篇简单的博客文章会更容易,这似乎与提出的问题密切相关