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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 01:24:02