ASP.NET MVC中如何通过Post Id为对应文章添加评论?
ASP.NET MVC 指定文章评论功能实现方案
第一步:修正模型关联关系
你当前的代码里Post和Comments没有绑定关系,评论无法关联到指定文章,且时间字段用字符串存储不便于后续处理,先调整两个模型:
- 给
Post类加评论导航属性,用来关联该文章下的所有评论 - 给
Comments类加文章外键PostId和对应导航属性,把时间字段改为DateTime类型
修正后的Post模型
namespace Post.Models { public class Post { public int Id { get; set; } public string Title { get; set; } public string SubTitle { get; set; } public string Content { get; set; } public string Date { get; set; } public string Image { get; set; } public string Slug { get; set; } // 新增:关联当前文章下的所有评论 public List<Comments> Comments { get; set; } = new List<Comments>(); } }
修正后的Comments模型
using System.ComponentModel.DataAnnotations; namespace Post.Models { public class Comments { public int Id { get; set; } [Required(ErrorMessage = "Please Enter Name")] public string Name { get; set; } [Required] public string Comment { get; set; } [Required] [RegularExpression(@"^[\w-\.]+@([\w-]+\.)+[\w-]{2,6}$", ErrorMessage = "Please provide Valid email")] public string Email { get; set; } // 修正:用DateTime类型存储时间,视图渲染时再做格式化 public DateTime CreateTime { get; set; } = DateTime.Now; // 新增:外键,绑定评论所属的文章ID public int PostId { get; set; } // 新增:导航属性,关联所属文章 public Post Post { get; set; } } }
模型修改完成后,执行EF的
Add-Migration和Update-Database命令更新数据库结构,否则外键字段不会生成。
第二步:调整控制器逻辑
你当前的评论提交逻辑没有接收文章ID、没有做数据校验、提交后无法跳回对应文章页,删掉无意义的GET版AddComment方法(评论不需要单独页面,直接嵌在文章详情页即可),按如下代码修改:
[HttpPost] [ValidateAntiForgeryToken] // 必加,防跨站请求伪造 public IActionResult AddComment(Comments mycomment) { // 先做数据校验,不通过则跳回原文章页,保留用户输入 if (!ModelState.IsValid) { TempData["CommentError"] = "请检查输入:姓名、有效邮箱、评论内容均为必填项"; TempData["PreFillComment"] = mycomment; var currentPost = db.Tbl_Post.Find(mycomment.PostId); return RedirectToAction("Post", "Home", new { Slug = currentPost.Slug }); } // 校验通过再入库 db.Tbl_Comments.Add(mycomment); db.SaveChanges(); // 跳回当前评论所属的文章详情页 var targetPost = db.Tbl_Post.Find(mycomment.PostId); return RedirectToAction("Post", "Home", new { Slug = targetPost.Slug }); } [Route("Home/Post/{Slug}")] public IActionResult Post(string Slug) { SharedLayOutData(); // 查询文章时同步查出关联的所有评论,按发布时间倒序排列 var DetailedPost = db.Tbl_Post .Include(p => p.Comments.OrderByDescending(c => c.CreateTime)) .FirstOrDefault(x => x.Slug == Slug); // 处理文章不存在的场景 if (DetailedPost == null) return NotFound(); return View(DetailedPost); }
第三步:修改文章详情视图
在Post.cshtml视图的正文区域下方,添加评论列表展示和评论提交表单,核心代码如下:
@model Post.Models.Post <!-- 你原来的文章正文展示代码保留 --> <div class="comment-area"> <h3>全部评论(@Model.Comments.Count)</h3> <!-- 展示已有评论 --> @foreach (var item in Model.Comments) { <div class="comment-item"> <div class="comment-meta"> <strong>@item.Name</strong> <span>@item.CreateTime.ToString("yyyy-MM-dd HH:mm")</span> </div> <p>@item.Comment</p> </div> } <!-- 评论提交表单 --> <h4>发表评论</h4> @if (TempData["CommentError"] != null) { <div class="alert alert-danger">@TempData["CommentError"]</div> } @{ var preFill = TempData["PreFillComment"] as Comments; } <form asp-action="AddComment" method="post"> <!-- 隐藏域传递当前文章ID --> <input type="hidden" name="PostId" value="@Model.Id" /> <div class="form-group"> <label>姓名</label> <input type="text" name="Name" class="form-control" value="@preFill?.Name" /> </div> <div class="form-group"> <label>邮箱(不会公开)</label> <input type="email" name="Email" class="form-control" value="@preFill?.Email" /> </div> <div class="form-group"> <label>评论内容</label> <textarea name="Comment" class="form-control" rows="4">@preFill?.Comment</textarea> </div> <button type="submit" class="btn btn-primary">提交评论</button> </form> </div>
注意事项
- 表单提交的字段名必须和
Comments模型的属性名一致,否则ASP.NET MVC的模型绑定会失效 - 生产环境建议加评论频率限制、敏感词过滤,避免垃圾评论
- 确保项目布局页已引用jQuery验证相关脚本,可按需添加前端实时校验
内容的提问来源于stack exchange,提问作者new developer
相关产品推荐
相关产品推荐

