我正在使用触发基本控制器操作方法的视图表单为我的ASP.NET MVC博客引擎创建评论系统:
FORM:
@if (User.Identity.IsAuthenticated)
{
//using (Html.BeginForm())
// {
<div class="new_comment">
<h6 id="shortcodes" class="page-header"><i class="fa fa-file-text-o"></i> Leave a comment</h6>
<div class="hline"></div>
<form class="form-horizontal" action="@Url.Action("CreateComment")" method="post" role="form">
<div class="form-group">
<div class="col-sm-4 col-md-4">
<textarea rows="7" class="form-control" name="Message" placeholder="Your Comment Here..."></textarea>
@Html.AntiForgeryToken()
<input type="hidden" name="Slug" value="@Model.Slug"/>
<input type="hidden" name="PostId" value="@Model.Id"/>
<br/>
</div>
</div>
<div class="form-group">
<input type="submit" value="Post Comment" class="btn btn-primary" style="margin-left: 12px"/>
</div>
</form>
</div>
//}
}
控制器:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult CreateComment([Bind(Include = "PostId,Message,Username,DatePosted")]Comment comment)
{
var post = db.BlogPosts.Find(comment.PostId);
if (post == null)
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
if (ModelState.IsValid)
{
comment.Username = User.Identity.GetUserId();
comment.DatePosted = DateTimeOffset.Now;
db.Comments.Add(comment);
db.SaveChanges();
}
return RedirectToAction("BlogPostDetails", new { slug = post.Slug});
}
我在if语句中包含的每个表达式旁边设置了断点,并确认传递的任何数据值("PostId, Message, Username, DatePosted")
都不为空,并且db.SaveChances()
正在提交更改数据库。接下来,这是Models.BlogPosts
...
模型:
public class BlogPosts
{
public BlogPosts()
{
this.Comments = new HashSet<Comment>();
}
public int Id { get; set; }
public DateTimeOffset Created { get; set; }
public DateTimeOffset? Updated { get; set; }
[AllowHtml]
[Required]
public string Title { get; set; }
public string Slug { get; set; }
[Required]
public string Category { get; set; }
[AllowHtml]
[Required]
public string Body { get; set; }
public string MediaURL { get; set; }
public bool Published { get; set; }
public virtual ICollection<Comment> Comments { get; set; }
}
public class Comment
{
public int Id { get; set; }
public int PostId { get; set; }
public string Username { get; set; }
[Required]
[DataType(DataType.MultilineText)]
public string Message { get; set; }
public DateTimeOffset DatePosted { get; set; }
public Nullable<System.DateTimeOffset> Edited { get; set; }
public virtual BlogPosts BlogPost { get; set; }
public virtual ApplicationUser Author { get; set; }
//public int? ParentId { get; set; }
//[ForeignKey("ParentId")]
//public virtual ICollection<Comment> Children { get; set; }
//public string ParentComment { get; internal set; }
}
这是无法执行的视图:
查看不执行
@foreach (var item in Model.Comments.OrderByDescending(c => c.DatePosted))
{
<div class="comment">
<p>
@if (item.Username == null)
{
<small>By: Anonymous</small><span>|</span>
}
else
{
<small>By: @Html.DisplayFor(modelItem => item.Username)</small><span>|</span>
}
<small>Date: @Html.DisplayFor(modelItem => item.DatePosted)</small>
@if (item.Edited != null)
{
<span>|</span><small>Updated: @Html.DisplayFor(modelItem => item.Edited)</small>
}
</p>
<div>
@Html.DisplayFor(modelItem => item.Message)
</div>
</div>
if (item.Username == User.Identity.GetUserId() || User.IsInRole("Admin") || User.IsInRole("Moderator"))
{
<div>
@Html.ActionLink("Edit", "_EditComment", new { id = item.Id }) <span>|</span>
@Html.ActionLink("Delete", "_DeleteComment", new { id = item.Id })
</div>
}
<br />
<!--<div class="hline"></div>-->
}
<div>
<input type="button" class="btn btn-primary" value="Return to Blog Roll" onclick="location.href = '@Url.Action("BlogIndex")'">
</div>
<br />
@if (User.Identity.IsAuthenticated || User.IsInRole("Admin") || User.IsInRole("Moderator"))
{
<input type="button" class="btn btn-primary" value="Modify Post" onclick="location.href = '@Url.Action("BlogAdmin")'">
<br />
<br />
}
在上面视图的第一行设置断点时:@foreach (var item in Model.Comments.OrderByDescending(c => c.DatePosted))
,引用
public virtual ICollection<Comment> Comments
类中的Models.BlogPosts
保持为空(这显然意味着我视图中的逻辑无法执行且未发布评论)。
我是ASP.NET MVC,EF Code-First等新手,显然不明白我的控制器如何将子模型中的注释值传递给父模型中的public virtual ICollection<Comment> Comments
。 ..我的Models.Comment
控制器中引用的CommentCreate
如何包含值,而我Models.BlogPosts
中的虚拟引用不相同?
编辑:在几位用户对我的代码中的修饰错误和严重错误以及有用的ASP.NET MVC资源指针的反馈非常好后,我确定传递的空引用已经过了在我的域模型中使用不正确的属性命名约定。见下面的答案。
答案 0 :(得分:1)
您包含PostId,但实际的属性名称是Id。您还需要显示您的视图所接收的模型。如果你对你所曝光的内容感到羞愧(例如Id,为什么不把它标记为隐藏字段?)。
在控制器中只传递您要编辑的模型,例如保留一个控制器仅用于网址路由,仅为您的对象保留您的模型,您的视图应仅适用于您传入的模型。
答案 1 :(得分:0)
最后发现我的BlogPost
域模型中public virtual BlogPosts BlogPost
中的Models.Comment
属性需要重命名,以匹配域模型的外键:public int PostId
。解决方案执行如下:
Post
,PostId
表中手动删除空Comment
值,update-database -f
命令。