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

如何在ASP.NET局部视图间传递用户ID参数

解决ASP.NET中循环传递用户ID到模态框的问题

问题说明

在ASP.NET项目的店铺详情页员工列表局部视图中,添加了标记员工病假的模态框局部视图。尝试用ViewBag传递循环中的用户ID(u.Id),但循环结束后ViewBag仅保留最后一个用户的ID,导致模态框内的表单无法将正确的用户ID传递给AddSicknessTimeCard控制器操作。

原代码分析

员工列表局部视图

@model Shop

<div class="mb-3 d-flex border-bottom align-items-center justify-content-between">
    <h3 class="text-secondary">Employees in @Model.Name</h3>

    <a asp-condition=@User.IsInRole("admin") asp-controller="User" asp-action="Register" asp-route-id="@Model.Id"
        class="btn-add-employee" title="Add a new user"><i class="bi bi-person-fill-add" ></i></a>

</div>

<table class="table table-sm">
    <thead>
        <tr>
            <th>Name</th>
            <th>Surname</th>
            <th>Role</th>
            <th>Edit Clock In-Out and Add Holiday Leave</th>
            <th>Sickness</th>
            <th></th>
        </tr>
    </thead>
    <tbody>
        @if (Model.Users.Count == 0)
        {
            <tr>
                <td colspan="4">No Employees...</td>
            </tr>
        }
        else
        {
            @foreach (var u in Model.Users)
            {
                
                var rowClass = "table-danger"; // Default to red

                 // Get today's timecard for the user
                 var todayTimeCard = u.TimeCards.Where(tc => tc.ClockIn.Date == DateTime.Today).OrderByDescending(tc => tc.ClockIn).FirstOrDefault();

                    if (todayTimeCard != null)
                    {
                        if (todayTimeCard.Holiday)
                        {
                            rowClass = "table-primary"; // Blue row for holiday
                        }
                        else if (todayTimeCard.Sickness)
                        {
                            rowClass = "table-warning"; // Yellow row for sickness
                        }
                        else
                        {
                            rowClass = "table-success"; // Green row for regular time card
                        }
                    }
               

                <tr class="@rowClass">
                    <td>@u.Name</td>
                    <td>@u.LastName</td>
                    <td>@u.Role</td>
                    <td>@u.ShopId</td>
                    <td> <a asp-condition=@User.HasOneOfRoles("manager,admin") asp-controller="User" asp-action="TimeCardLog" asp-route-id="@u.Id"
                            class="btn"><i class="bi bi-pencil-fill"></i></a>
                    </td>
                    <td>
                          @{ViewBag.UserId = u.Id;}
                          <button asp-condition=@User.HasOneOfRoles("manager,admin") data-bs-toggle="modal" data-bs-target="#AddSicknessTimeCardModal"
                    class="btn btn-sm btn-outline-warning"><i class="bi bi-emoji-frown" title="mark as sick"></i>Mark as Sick</button>
                    </td>

                    <td class="text-end">

                        <a asp-condition=@User.IsInRole("admin") asp-controller="User" asp-action="Edit" asp-route-id="@u.Id"
                            class="btn btn-sm btn-outline-dark">Edit employee details</a>
                        <br>

                        <a asp-condition=@User.IsInRole("admin") asp-controller="User" asp-action="Delete" asp-route-id="@u.Id"
                            class="buttondelete btn-sm btn-outline-danger">
                            <i class="bi bi-trash" title="Delete User"></i>Remove employee</a>
                        <br>

                        <a asp-condition=@User.IsInRole("admin") asp-controller="User" asp-action="ReassignShop" asp-route-id="@u.Id"
                            class="buttondelete btn-sm btn-outline-danger">
                            <i class="bi bi-arrow-right" title="Reassign User"></i>Re-assign employee</a>

                    </td>
                   
                </tr>
            }
        }
    </tbody>
</table>



<!-- Mark as sickness Modal Confirmation -->
<partial name="_AddSicknessTimeCardModal" />

模态框局部视图

<!-- Modal -->
<div class="modal fade" id="AddSicknessTimeCardModal" tabindex="-1" aria-hidden="true">
    <div class="modal-dialog">
        <div class="modal-content">
            <div class="modal-header">
                <h1 class="modal-title fs-5" id="exampleModalLabel">Mark Absence</h1>
                <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
            </div>
            <div class="modal-body">
                <div class="alert alert-warning">
                    <h3>Are you sure you want to mark this person as being sick today?</h3>
                </div>
                <div class="modal-footer">

                    <form asp-action="AddSicknessTimeCard" method="post" asp-route-id="@ViewBag.UserId">
                        <button type="submit" class="btn btn-primary" aria-label="add">Yes</button>
                        <button type="button" class="btn btn-danger" data-bs-dismiss="modal">Cancel</button>
                    </form>
                </div>
            </div>
        </div>
    </div>
</div>

问题根源:ViewBag是服务器端全局对象,循环中每次赋值都会覆盖之前的值,而模态框是在循环结束后渲染的,因此只能获取到最后一次赋值的用户ID。


解决方案

方法一:用JavaScript动态设置表单参数

这种方法只保留一个模态框,通过按钮的自定义属性存储用户ID,在模态框显示时动态修改表单的参数。

  1. 修改员工列表中的按钮,添加data-user-id属性存储当前用户ID:
<button asp-condition=@User.HasOneOfRoles("manager,admin") data-bs-toggle="modal" data-bs-target="#AddSicknessTimeCardModal"
        data-user-id="@u.Id" class="btn btn-sm btn-outline-warning">
    <i class="bi bi-emoji-frown" title="mark as sick"></i>Mark as Sick
</button>
  1. 修改模态框的表单,添加隐藏域用于存储用户ID:
<form id="sicknessForm" asp-action="AddSicknessTimeCard" method="post">
    <input type="hidden" id="userIdInput" name="id" value="">
    <button type="submit" class="btn btn-primary" aria-label="add">Yes</button>
    <button type="button" class="btn btn-danger" data-bs-dismiss="modal">Cancel</button>
</form>
  1. 添加JavaScript监听模态框显示事件,动态设置隐藏域的值:
const sicknessModal = document.getElementById('AddSicknessTimeCardModal');
sicknessModal.addEventListener('show.bs.modal', function (event) {
    // 获取触发模态框的按钮
    const triggerBtn = event.relatedTarget;
    // 获取按钮上存储的用户ID
    const userId = triggerBtn.getAttribute('data-user-id');
    // 设置表单隐藏域的值
    document.getElementById('userIdInput').value = userId;
});

方法二:为每个员工生成独立模态框

这种方法在循环内为每个员工渲染专属的模态框,每个模态框使用唯一ID,直接绑定当前用户ID,无需额外JS。

  1. 修改员工列表中的按钮,将data-bs-target设置为唯一的模态框ID:
<button asp-condition=@User.HasOneOfRoles("manager,admin") data-bs-toggle="modal" data-bs-target="#AddSicknessTimeCardModal-@u.Id"
        class="btn btn-sm btn-outline-warning">
    <i class="bi bi-emoji-frown" title="mark as sick"></i>Mark as Sick
</button>
  1. 在循环内部渲染模态框局部视图,传递当前用户ID作为模型:
<partial name="_AddSicknessTimeCardModal" model="@u.Id" />
  1. 修改模态框局部视图,接收用户ID并设置唯一ID和路由参数:
@model int

<div class="modal fade" id="AddSicknessTimeCardModal-@Model" tabindex="-1" aria-hidden="true">
    <div class="modal-dialog">
        <div class="modal-content">
            <div class="modal-header">
                <h1 class="modal-title fs-5" id="exampleModalLabel">Mark Absence</h1>
                <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
            </div>
            <div class="modal-body">
                <div class="alert alert-warning">
                    <h3>Are you sure you want to mark this person as being sick today?</h3>
                </div>
                <div class="modal-footer">
                    <form asp-action="AddSicknessTimeCard" method="post" asp-route-id="@Model">
                        <button type="submit" class="btn btn-primary" aria-label="add">Yes</button>
                        <button type="button" class="btn btn-danger" data-bs-dismiss="modal">Cancel</button>
                    </form>
                </div>
            </div>
        </div>
    </div>
</div>

方法对比

  • 方法一:仅渲染一个模态框,减少DOM元素数量,适合员工数量较多的场景,需要少量JS逻辑。
  • 方法二:逻辑直观,无需JavaScript,适合员工数量较少的场景,每个员工对应一个模态框,DOM元素会随员工数量增加而增多。

内容的提问来源于stack exchange,提问作者molly1312

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 10:37:32