
本文介绍在 razor 页面中使用 @foreach 循环渲染多条数据时,如何避免因复用同一
在 ASP.NET Core Razor Pages 中,当在 @foreach 循环内渲染多个删除操作按钮并共用同一个
✅ 正确做法:为每个对话框分配唯一 ID,并将当前实验 ID 作为参数传入 JS 函数。修改要点如下:
-
为
添加动态 ID (例如 deleteDialog_@experiment.Id); - 在 标签中传入当前 @experiment.Id 到 showDeleteDialog();
- 更新 JS 函数,接收 ID 并精准定位对应 dialog;
- 确保
以下是修正后的完整代码示例:
<form method="post">
<table class="table table-striped">
<thead>
<tr>
<th>Id</th>
<th>Name</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
@foreach (var experiment in Model.MainExperimentsTests)
{
<tr>
<td>@experiment.Id</td>
<td>@experiment.ExperimentTestName</td>
<td>
<a class="btn btn-sm btn-danger permissionRead permissionWrite"
onclick="showDeleteDialog(@experiment.Id)">
<i class="bi-bucket"></i> Delete
</a>
<dialog id="deleteDialog_@experiment.Id">
<p>Do you really want to delete experiment <strong>@experiment.ExperimentTestName</strong> (ID: @experiment.Id)?</p>
<form method="post">
<button type="submit"
asp-page-handler="Delete"
asp-route-experimentId="@experiment.Id"
class="btn btn-primary">
Confirm
</button>
<button type="button"
onclick="closeDeleteDialog(@experiment.Id)"
class="btn btn-secondary">
Cancel
</button>
</form>
</dialog>
</td>
</tr>
}
</tbody>
</table>
</form>
<script>
function showDeleteDialog(experimentId) {
const dialog = document.getElementById(`deleteDialog_${experimentId}`);
if (dialog) dialog.showModal();
}
function closeDeleteDialog(experimentId) {
const dialog = document.getElementById(`deleteDialog_${experimentId}`);
if (dialog) dialog.close();
}
</script>⚠️ 注意事项:
必须在循环内部声明,确保每个 experiment 拥有独立的、带唯一 ID 的 dialog 实例; - asp-route-experimentId="@experiment.Id" 是服务器端 Razor 渲染的静态属性,无需 JS 动态赋值 —— 它已在 HTML 输出时固化到对应按钮的 form 中;
- 推荐为
- 若 experiment.Id 可能含特殊字符(如 -、.),建议在 ID 中做简单转义(如 @experiment.Id.ToString().Replace("-", "_")),但整型 ID 通常无需处理;
- 现代浏览器对
支持良好(Chrome 37+, Edge 79+, Firefox 98+),生产环境建议添加 dialog-polyfill 兼容旧版。
通过此结构,每个删除操作完全解耦,asp-route-experimentId 将准确传递对应行的数据 ID,彻底解决“总是删第一个”的问题。










