我正在开发asp.net MVC 5项目。我有两个模型Post和Comment,它们之间有一对多的关系。在Post的详细信息视图中,我想在该帖子中添加评论。如何在不使用任何ViewModel的情况下执行此操作?仅在视图中传递Post模型。我想通过使用Post模型引用访问Comment及其属性,毕竟它们之间有很多关系,Post模型有评论的参考。
这是我的代码示例 Post's控制器中的详细操作
[HttpPost]
public ActionResult Details(Comment comment, string post_id)
{
int id = int.Parse(post_id);
if (ModelState.IsValid)
{
var post = db.Posts.FirstOrDefault(u => u.id == id);
comment.post = post;
db.Comments.Add(comment);
db.SaveChanges();
return RedirectToAction("Index");
}
return View(comment);
}
//
// GET: /Post/Details/5
public ActionResult Details(int id = 0)
{
Post post = db.Posts.Find(id);
if (post == null)
{
return HttpNotFound();
}
return View(post);
}
这里是Details.schtml
@model Blog.Models.Post
@{
ViewBag.Title = "Details";
}
<h2>Details</h2>
<fieldset>
<legend>Post</legend>
<div class="display-label">
@Html.DisplayNameFor(model => model.title)
</div>
<div class="display-field">
@Html.DisplayFor(model => model.title)
</div>
<div class="display-label">
@Html.DisplayNameFor(model => model.body)
</div>
<div class="display-field">
@Html.DisplayFor(model => model.body)
</div>
@for (int i = 0; i <Model.comments.Count; i++)
{
<div class="display-label">
@Html.DisplayNameFor(model => model.comments[i].comment)
</div>
<div class="display-field">
@Html.DisplayFor(model => model.comments[i].comment)
</div>
}
<h2>Comment</h2>
@using (Html.BeginForm())
{
@Html.ValidationSummary(true)
<fieldset>
<legend>Article</legend>
<div class="editor-label">
@Html.LabelFor(model =>model.comments[Model.comments.Count].comment)
</div>
<div class="editor-field">
@Html.EditorFor(model =>model.comments[Model.comments.Count].comment))
@Html.ValidationMessageFor(model => model.comments[Model.comments.Count].comment)
</div>
<p>
<input type="submit" value="Add" />
</p>
</fieldset>
}
</fieldset>
有错误
&#34;指数超出范围。必须是非负数且小于集合的大小。\ r \ n参数名称:index&#34;
如何成功添加评论?
答案 0 :(得分:1)
错误本身几乎解释了这个问题。在您收到错误的行上,Model.comments.Count
超出了范围。索引从0开始,因此应该以{{1}}的方式检索最后一条注释。
答案 1 :(得分:1)
您的异常由视图中的以下行生成
@Html.LabelFor(model =>model.comments[Model.comments.Count].comment)
也将由后续EditorFor()
和ValidationMessageFor()
方法生成。
集合索引器基于零,而.Count()
返回集合中的项目数。如果您说集合包含2 Comment
,那么您可以将其作为
model.Comments[0].comment
model.Comments[1].comment
但您的[Model.comments.Count]
等同于
model.Comments[2].comment
抛出异常,因为您引用了集合中的第3个项目(不存在)。即使您引用了集合中的现有项目,您的代码也会失败,因为您将回发一个集合(由索引器定义),但POST方法仅排除单个对象
您似乎想要向Post
添加新评论,在这种情况下,您可以使用包含Comment
的附加属性的视图模型
public Comment NewComment { get; set; }
然后在您查看中,使用
生成表单控件@Html.EditorFor(m => m.NewComment.comment)
并将POST方法签名更改为
public ActionResult Details([Bind(Prefix = "NewComment")]Comment comment, int post_id)
请注意使用Bind.Prefix
属性来删除发布到方法的名称/值对中的"NewComment"
前缀。另请注意,您可以创建第二个参数int
并避免从string
到int
的不必要转换(尽管您似乎没有为属性post_id
生成表单控件所以它无论如何都会null
。
另一种方法是使用@Html.Action()
调用子操作方法,该方法根据新的Comment
返回部分视图(包含表单)。
答案 2 :(得分:0)
这是因为db.Posts.Find(id);
。您已在public ActionResult Details(int id = 0)
中为ID提供了初始值。检查您的代码,确保始终将值传递给id。