ASP.NET Core MVC中Create视图提交后更新局部视图列表问题求助
解决方案
核心思路
保持Create视图使用单个Record模型处理表单提交,通过两次AJAX请求实现需求:
- 页面加载完成后,异步获取最新10条记录渲染局部视图
- 表单提交成功后,重新获取最新记录更新局部视图
同时修复防伪造令牌传递、局部视图语法错误等问题。
1. 修改Create视图
表单添加防伪造令牌
在<form>标签内添加@Html.AntiForgeryToken(),匹配Controller的[ValidateAntiForgeryToken]校验:
<form asp-action="Create" id="postForm"> @Html.AntiForgeryToken() <div asp-validation-summary="ModelOnly" class="text-danger"></div> <div class="form-group"> <label asp-for="CardId" class="control-label"></label> <input asp-for="CardId" class="form-control" /> <span asp-validation-for="CardId" class="text-danger"></span> </div> <div class="form-group"> <input type="button" id="addBtn" value="Create" class="btn btn-primary" /> </div> </form>
调整Scripts部分
添加初始加载列表的逻辑,同时在AJAX请求中传递防伪造令牌:
@section Scripts { @{await Html.RenderPartialAsync("_ValidationScriptsPartial");} <script src="https://code.jquery.com/jquery-3.7.1.min.js"></script> <script> // 页面加载完成后初始化最新记录列表 $(function () { loadLatestRecords(); $("#addBtn").click(function (event) { event.preventDefault(); // 获取防伪造令牌值 var token = $('input[name="__RequestVerificationToken"]').val(); $.ajax({ url: '@Url.Action("Create", "Record")', type: "POST", headers: { "RequestVerificationToken": token // 传递防伪造令牌 }, data: $("#postForm").serialize(), success: function (data) { if (data.success) { $("#itemlist").html(data.html); $("#postForm")[0].reset(); } else { // 模型验证失败时更新表单验证信息 $("#postForm").html(data.html); } }, error: function () { alert("Failed to save data. Please try again."); } }); }); }); // 加载最新10条记录的函数 function loadLatestRecords() { $.ajax({ url: '@Url.Action("GetLatestRecords", "Record")', type: "GET", success: function (data) { $("#itemlist").html(data); }, error: function () { alert("Failed to load records."); } }); } </script> }
2. 修正局部视图_RecordPartialView的HTML错误
原代码中table的class属性语法错误,修正为:
@model IEnumerable<ScanInRecords.Models.Record> <table class="table table-bordered table-striped" border="1"> <thead> <tr> <th>@Html.DisplayNameFor(model => model.CardId)</th> <th>@Html.DisplayNameFor(model => model.ScanInTime)</th> </tr> </thead> <tbody> @foreach (var item in Model) { <tr> <td>@Html.DisplayFor(modelItem => item.CardId)</td> <td>@Html.DisplayFor(modelItem => item.ScanInTime)</td> </tr> } </tbody> </table>
3. 扩展RecordController
添加一个新的GetLatestRecords方法用于获取最新记录,同时修改Create POST方法返回JSON格式的结果,区分成功/失败状态:
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.ViewEngines; using ScanInRecords.Models; using ScanInRecords.Repository; using System.IO; namespace ScanInRecords.Controllers { public class RecordController : Controller { private readonly IRecordRepository _iRecordRepository; private readonly ICompositeViewEngine _viewEngine; public RecordController(IRecordRepository iRecordRepository, ICompositeViewEngine viewEngine) { _iRecordRepository = iRecordRepository; _viewEngine = viewEngine; } // 新增:获取最新10条记录的方法 public async Task<IActionResult> GetLatestRecords() { var latestRecords = await _iRecordRepository.GetAllAsync(); return PartialView("_RecordPartialView", latestRecords); } public async Task<IActionResult> Index() { var result = await _iRecordRepository.GetAllAsync(); return View(result); } [HttpGet] public IActionResult Create() { return View(); } [HttpPost] [ValidateAntiForgeryToken] public async Task<IActionResult> Create(Record record) { if (ModelState.IsValid) { record.ScanInTime = DateTime.Now; await _iRecordRepository.Create(record); var latestRecords = await _iRecordRepository.GetAllAsync(); var partialViewHtml = await RenderViewToStringAsync("_RecordPartialView", latestRecords); return Json(new { success = true, html = partialViewHtml }); } // 模型验证失败时,返回表单的HTML var formHtml = await RenderViewToStringAsync("Create", record); return Json(new { success = false, html = formHtml }); } // 辅助方法:将视图渲染为字符串 private async Task<string> RenderViewToStringAsync(string viewName, object model) { ViewData.Model = model; using (var sw = new StringWriter()) { var viewResult = _viewEngine.FindView(ControllerContext, viewName, false); var viewContext = new ViewContext(ControllerContext, viewResult.View, ViewData, TempData, sw, new HtmlHelperOptions()); await viewResult.View.RenderAsync(viewContext); return sw.GetStringBuilder().ToString(); } } } }
关键说明
- 防伪造令牌:ASP.NET Core的
[ValidateAntiForgeryToken]要求请求携带令牌,AJAX通过headers传递避免400错误 - 初始加载列表:页面加载后调用
loadLatestRecords,确保打开Create页面时就显示最新记录 - 模型验证处理:POST方法返回JSON,成功时返回局部视图HTML,失败时返回表单HTML,保证验证提示正常显示
- 辅助方法
RenderViewToStringAsync:将视图转换为字符串,方便通过JSON返回给前端
内容的提问来源于stack exchange,提问作者CasperL
相关产品推荐
相关产品推荐

