ASP.NET Core Razor视图中如何从表单向模型列表添加对象
问题描述
我有一个包含Awards列表的ActivityForm模型,需要在ASP.NET Core Razor视图中,通过模态框内的表单创建Award对象,将其添加到模型的Awards列表中,并且让视图实时显示新增对象,暂不保存至数据库。
模型代码
public class ActivityForm { public string Name { get; set; } public string Description { get; set; } public DateTime StartDate { get; set; } public DateTime EndDate { get; set; } public int Points { get; set; } public List<Award> Awards { get; set; } }
现有视图代码
@model ActivityForm @{ ViewData["Title"] = "Activity Details"; } <section class="my-sm-5"> <div class="container"> <div class="section-header d-flex mb-5"> <h1 class="h-02 flex-grow-1">Activity Details</h1> </div> <div class="row"> <div class="col-md-7"> <div class="section-header d-flex mb-5"> <h1 class="h-04 flex-grow-1">Form</h1> </div> <form id="form" class="row g-3 w-90" asp-action="Create"> <div class="col-md-12"> <label asp-for="Name" class="form-label">@Html.DisplayNameFor(model => model.Name)</label> <input asp-for="Name" type="text" class="form-control" id="inputEmail4" placeholder="@Html.DisplayNameFor(model => model.Name)"> <span asp-validation-for="Name" class="invalid-feedback"></span> </div> <div class="col-12"> <label asp-for="Description" class="form-label">@Html.DisplayNameFor(model => model.Description)</label> <textarea asp-for="Description" class="form-control" id="exampleFormControlTextarea1" rows="5" placeholder="@Html.DisplayNameFor(model => model.Description)"></textarea> <span asp-validation-for="Description" class="invalid-feedback"></span> </div> <div class="col-md-4"> <label asp-for="StartDate" class="form-label">@Html.DisplayNameFor(model => model.StartDate)</label> <input asp-for="StartDate" type="date" class="form-control" placeholder="@Html.DisplayNameFor(model => model.StartDate)"> <span asp-validation-for="StartDate" class="invalid-feedback"></span> </div> <div class="col-md-4"> <label asp-for="EndDate" class="form-label">@Html.DisplayNameFor(model => model.EndDate)</label> <input asp-for="EndDate" type="date" class="form-control" placeholder="@Html.DisplayNameFor(model => model.EndDate)"> <span asp-validation-for="EndDate" class="invalid-feedback"></span> </div> <div class="col-md-4 mb-6"> <label asp-for="Points" class="form-label">@Html.DisplayNameFor(model => model.Points)</label> <input asp-for="Points" type="number" class="form-control" placeholder="@Html.DisplayNameFor(model => model.Points)"> <span asp-validation-for="Points" class="invalid-feedback"></span> </div> <div class="col-8 d-grid gap-2"> <a class="btn btn-primary mb-2" data-bs-toggle="modal" data-bs-target="#add-award">Add award</a> <div class="row"> <div class="col-md-6"> <a class="btn btn-outline-primary w-100" data-bs-toggle="modal" data-bs-target="#cancel-activity">Cancel</a> </div> <div class="col-md-6"> <a class="btn btn-outline-primary w-100" data-bs-toggle="modal" data-bs-target="#post-activity">Post Activity</a> </div> </div> </div> </form> </div> <div class="col-md-5"> <div class="section-header d-flex mb-5"> <h1 class="h-04 flex-grow-1">Awards</h1> </div> <table class="table"> <thead> <tr> <th scope="col">Award name</th> <th scope="col">Description</th> <th scope="col"></th> </tr> </thead> <tbody> @for (int i = 0; i < 1; i++) { <tr> <td>Award Name</td> <td>Award Description</td> <td> <a class="btn btn-outline-primary btn-sm">Edit</a> <a class="btn btn-outline-primary btn-sm">Remove</a> </td> </tr> } </tbody> </table> </div> </div> </div> </section> <div class="modal" id="add-award" tabindex="-1"> <div class="modal-dialog modal-dialog-centered"> <div class="modal-content br-20 pd-20"> <div class="modal-header justify-content-center"> <h5 class="modal-title h-04 text-prim-color">Award details</h5> </div> <form class="row g-3"> <div class="modal-body"> <div class="row g-3"> <div class="col-md-12"> <label asp-for="Award.Name" class="form-label">Name</label> <input asp-for="Award.Name" type="text" class="form-control" id="inputEmail4"> </div> <div class="col-12"> <label asp-for="Award.Description" for="inputAddress" class="form-label">Description</label> <textarea asp-for="Award.Description" class="form-control" id="exampleFormControlTextarea1" rows="5"></textarea> </div> </div> </div> <div class="modal-footer justify-content-center"> <button type="button" class="btn btn-outline-primary w-100" data-bs-dismiss="modal">Close</button> <input class="btn btn-primary w-100" type="submit" value="Confirm"></input> </div> </form> </div> </div> </div>
核心需求
点击模态框的「Confirm」按钮时,根据表单输入值创建Award对象,添加到ActivityForm的Awards列表中,同时让右侧Awards表格实时显示新增对象。
解决方案
1. 修正Awards表格渲染逻辑
将硬编码的循环改为遍历模型的Awards列表,同时给表格tbody添加ID方便后续JS操作:
<tbody id="awards-table-body"> @if (Model.Awards != null && Model.Awards.Any()) { @foreach (var award in Model.Awards) { <tr> <td>@award.Name</td> <td>@award.Description</td> <td> <a class="btn btn-outline-primary btn-sm">Edit</a> <a class="btn btn-outline-primary btn-sm">Remove</a> </td> </tr> } } else { <tr> <td colspan="3" class="text-center">No awards added yet</td> </tr> } </tbody>
2. 修正模态框表单控件
移除错误的asp-for绑定,给输入框设置明确ID:
<div class="modal-body"> <div class="row g-3"> <div class="col-md-12"> <label class="form-label">Name</label> <input type="text" class="form-control" id="award-name"> </div> <div class="col-12"> <label class="form-label">Description</label> <textarea class="form-control" id="award-description" rows="5"></textarea> </div> </div> </div>
同时给模态框表单添加ID:
<form class="row g-3" id="add-award-form">
3. 添加JavaScript提交逻辑
在视图末尾添加脚本,处理表单提交、创建表格行并更新视图:
<script> document.getElementById('add-award-form').addEventListener('submit', function(e) { e.preventDefault(); // 阻止默认提交行为 // 获取输入值 const awardName = document.getElementById('award-name').value.trim(); const awardDesc = document.getElementById('award-description').value.trim(); if (!awardName) { alert('Award name is required'); return; } // 创建新表格行 const tableBody = document.getElementById('awards-table-body'); const newRow = document.createElement('tr'); newRow.innerHTML = ` <td>${awardName}</td> <td>${awardDesc}</td> <td> <a class="btn btn-outline-primary btn-sm">Edit</a> <a class="btn btn-outline-primary btn-sm" onclick="this.parentElement.parentElement.remove()">Remove</a> </td> `; // 移除空状态行(如果存在) const emptyRow = tableBody.querySelector('tr[colspan="3"]'); if (emptyRow) emptyRow.remove(); // 添加新行到表格 tableBody.appendChild(newRow); // 重置表单并关闭模态框 this.reset(); const modal = bootstrap.Modal.getInstance(document.getElementById('add-award')); modal.hide(); }); </script>
4. 后端初始化Awards列表(可选)
在控制器Action中初始化Awards列表,避免空引用:
public IActionResult Create() { var model = new ActivityForm { Awards = new List<Award>() }; return View(model); }
内容的提问来源于stack exchange,提问作者craig_ck
相关产品推荐
相关产品推荐

