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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 14:00:48