ASP.NET MVC如何通过PostId实现指定博文的评论添加与查询
ASP.NET MVC 博文评论关联与按PostId筛选实现方案
问题根因
SharedLayOutData方法直接将全量评论表数据存入ViewBag,未按当前访问博文的PostId做筛选,导致详情页加载全站点所有评论- 评论提交接口未接收当前博文的PostId参数,提交时评论实体的PostId为默认值0,无法和对应博文建立关联关系
- 详情页视图直接读取全局ViewBag中的全量评论集合,没有绑定当前博文的专属评论数据
分步修复代码
1. 调整详情页控制器逻辑,实现评论按PostId筛选
首先删除SharedLayOutData方法中ViewBag.Comments = db.Tbl_Comments;这行代码,全局不需要加载全量评论。
找到博文详情对应的Action(即评论提交后跳转的Home控制器下的Post方法),修改为按当前博文ID查询关联评论:
public IActionResult Post(int id) { // 查询当前访问的博文实体 var currentPost = db.Tbl_Post.FirstOrDefault(p => p.Id == id); if (currentPost == null) { return NotFound(); } // 核心筛选:只查询当前博文关联的评论,按发布时间倒序排列 var relatedComments = db.Tbl_Comments .Where(c => c.PostId == id) .OrderByDescending(c => c.dateTime) .ToList(); ViewBag.RelatedComments = relatedComments; // 保留全局公共数据加载 ViewBag.Profile = db.Tbl_Profile.FirstOrDefault(); return View(currentPost); }
2. 修复评论提交逻辑,绑定博文关联关系
修改AddComment接口,接收当前博文ID参数,提交时手动给评论实体绑定PostId,确保关联关系正确:
[HttpPost] [ValidateAntiForgeryToken] public IActionResult AddComment(Comments mycomment, int postId) { // 校验目标博文是否存在 var targetPost = db.Tbl_Post.FirstOrDefault(p => p.Id == postId); if (targetPost == null) { return NotFound(); } if (ModelState.IsValid) { // 绑定评论所属博文ID mycomment.PostId = postId; mycomment.dateTime = DateTime.Now.ToString(); db.Tbl_Comments.Add(mycomment); db.SaveChanges(); // 提交成功后跳回当前博文详情页 return RedirectToAction("Post", "Home", new { id = postId }); } // 模型验证失败时返回详情页并提示错误 TempData["CommentErrMsg"] = "评论信息填写不完整,请检查昵称、邮箱格式和评论内容后重新提交"; return RedirectToAction("Post", "Home", new { id = postId }); }
注:原有的无参数
AddCommentGET方法可以删除,评论表单直接放在博文详情页即可,不需要单独的评论提交页面。
3. 修改详情页视图,展示关联评论+提交表单
替换原有详情页中评论区的代码,改为读取筛选后的关联评论,同时新增评论提交表单,通过隐藏字段传递当前博文ID:
@using Post.Models @using System.Web @model Post @{ // 读取当前博文的关联评论 IEnumerable<Comments> mycomments = ViewBag.RelatedComments ?? new List<Comments>(); var errMsg = TempData["CommentErrMsg"]?.ToString(); } <!-- 原有博文内容展示块保持不变 --> <div class="w3-card-4 w3-margin w3-white"> <img src="~/images/@Model.Image" alt="Nature" style="width:100%"> <div class="w3-container"> <hr> <h3><b>@Model.Title</b></h3> <hr> <h5>@Model.SubTitle ,<span class="w3-opacity">@Model.Date</span></h5> <hr> </div> <div class="w3-container"> <p> @Html.Raw(HttpUtility.HtmlDecode(Model.Content)) </p> <div class="w3-row"></div> </div> </div> <div class="container comment_section"> <section class="comments_top"> <div class="container"> <div class="row"> <div class="col-sm-5 col-md-6 col-12 pb-4"> <h1>Comments</h1> @if (!mycomments.Any()) { <p>暂无评论,快来发布第一条评论吧</p> } @foreach (var item in mycomments) { <div class="comment mt-4 text-justify float-left"> <img src="https://i.imgur.com/yTFUilP.jpg" alt="" class="rounded-circle" width="40" height="40"> <h4>@item.Name</h4> <span>@item.dateTime</span> <br> <p>@item.Comment</p> </div> } </div> <!-- 评论提交表单 --> <div class="col-lg-4 col-md-5 col-sm-4 offset-md-1 offset-sm-1 col-12 mt-4"> @if (!string.IsNullOrEmpty(errMsg)) { <div class="alert alert-danger">@errMsg</div> } <form asp-action="AddComment" asp-controller="Home" method="post"> @Html.AntiForgeryToken() <!-- 隐藏字段传递当前博文ID --> <input type="hidden" name="postId" value="@Model.Id" /> <div class="form-group mb-3"> <label>昵称</label> <input type="text" name="Name" class="form-control" required /> </div> <div class="form-group mb-3"> <label>邮箱</label> <input type="email" name="Email" class="form-control" required /> </div> <div class="form-group mb-3"> <label>评论内容</label> <textarea name="Comment" class="form-control" rows="4" required></textarea> </div> <button type="submit" class="btn btn-primary">提交评论</button> </form> </div> </div> </div> </section> </div>
可选优化项
- 将
Comments模型中的dateTime属性从string类型改为DateTime类型,存储、排序效率更高,展示时在视图调用.ToString("yyyy-MM-dd HH:mm")格式化即可 - 评论提交逻辑可增加基础的敏感词过滤、频率限制,减少垃圾评论
- 全局布局方法仅加载所有页面公用的数据(如站点配置、登录态信息),不要加载全量表数据,避免不必要的性能开销
内容的提问来源于stack exchange,提问作者new developer
相关产品推荐
相关产品推荐

