ASP.NET Razor 如何为对象列表创建POST表单实现动态新增带多课时的课程
实现动态Lesson表单的Razor页面新增Course方案
第一步:配置PageModel后端代码
创建Create.cshtml.cs后端文件,绑定提交数据并实现入库逻辑:
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.RazorPages; using 你的项目命名空间.Data; using 你的项目命名空间.Models; namespace 你的项目命名空间.Pages.Courses { public class CreateModel : PageModel { private readonly ApplicationDbContext _context; public CreateModel(ApplicationDbContext context) { _context = context; } // 自动绑定前台提交的Course完整数据 [BindProperty] public Course Course { get; set; } public IActionResult OnGet() { // 初始化默认展示1个Lesson输入块,也可设置为空 Course = new Course { Lessons = new List<Lesson> { new Lesson() } }; return Page(); } public async Task<IActionResult> OnPostAsync() { if (!ModelState.IsValid) { return Page(); } // EF Core会自动关联保存Course和对应的Lesson集合到两张表 _context.Courses.Add(Course); await _context.SaveChangesAsync(); return RedirectToPage("Index"); } } }
第二步:编写前端Razor页面代码
创建Create.cshtml视图文件,渲染基础表单结构:
@page @model 你的项目命名空间.Pages.Courses.CreateModel @{ ViewData["Title"] = "新增课程"; } <h1>新增课程信息</h1> <form method="post"> <!-- Course基础信息输入区域 --> <div class="form-group mb-3"> <label asp-for="Course.Category">课程分类</label> <input asp-for="Course.Category" class="form-control" /> <span asp-validation-for="Course.Category" class="text-danger"></span> </div> <div class="form-group mb-3"> <label asp-for="Course.Title">课程标题</label> <input asp-for="Course.Title" class="form-control" /> <span asp-validation-for="Course.Title" class="text-danger"></span> </div> <hr /> <h3>课时信息</h3> <!-- 动态Lesson表单容器 --> <div id="lessonContainer" class="mb-3"> @for (int i = 0; i < Model.Course.Lessons.Count; i++) { <div class="lesson-item border p-3 mb-3 rounded"> <div class="form-group mb-2"> <label>课时标题</label> <input name="Course.Lessons[@i].Title" class="form-control" /> </div> <div class="form-group mb-2"> <label>课时内容</label> <textarea name="Course.Lessons[@i].Text" class="form-control" rows="3"></textarea> </div> <button type="button" class="btn btn-danger btn-sm delete-lesson">删除当前课时</button> </div> } </div> <button type="button" id="addLessonBtn" class="btn btn-secondary mb-3">新增课时</button> <br> <button type="submit" class="btn btn-primary">提交全部信息</button> </form>
第三步:添加JS实现动态新增/删除Lesson块
在视图末尾添加脚本,实现自定义Lesson数量的交互逻辑:
@section Scripts { <script> // 新增课时逻辑 document.getElementById('addLessonBtn').addEventListener('click', function () { const container = document.getElementById('lessonContainer'); // 取当前已有课时数量作为新块的索引,符合ASP.NET Core模型绑定规则 const newIndex = container.querySelectorAll('.lesson-item').length; const newLessonBlock = ` <div class="lesson-item border p-3 mb-3 rounded"> <div class="form-group mb-2"> <label>课时标题</label> <input name="Course.Lessons[${newIndex}].Title" class="form-control" /> </div> <div class="form-group mb-2"> <label>课时内容</label> <textarea name="Course.Lessons[${newIndex}].Text" class="form-control" rows="3"></textarea> </div> <button type="button" class="btn btn-danger btn-sm delete-lesson">删除当前课时</button> </div> `; container.insertAdjacentHTML('beforeend', newLessonBlock); }); // 委托绑定删除逻辑,动态新增的块也可生效 document.getElementById('lessonContainer').addEventListener('click', function (e) { if (e.target.classList.contains('delete-lesson')) { e.target.closest('.lesson-item').remove(); // 无需重新调整索引,ASP.NET Core模型绑定天然支持非连续整数索引 } }); </script> }
补充说明
- 如果需要表单验证,可给实体类属性添加
[Required]等验证特性,前后端验证会自动生效 - 本方案支持任意数量的Lesson新增、删除操作,不需要提前固定Lesson数量
- 实体类主键为Guid类型,EF Core会自动生成主键值,无需手动赋值
内容的提问来源于stack exchange,提问作者Ilya Vasunin
相关产品推荐
相关产品推荐

