You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 05:24:52