ASP.NET Core中如何从表格行点击事件获取多个ID并传递至删除接口
解决多ID逐一删除的405错误及正确实现方案
看起来你在实现表格中多个记录的逐一删除功能时遇到了路由和参数传递的问题,405错误主要是因为HTTP方法不匹配或者路由参数不正确导致的,咱们一步步来修复:
1. 修正Controller的删除方法
首先,你的需求是逐一删除每个ID对应的记录,所以不需要在路由里传递5个ID参数,只需要单个ID即可。另外原Get方法的查询逻辑有问题(x.Id == Id && x.Id == Id2 永远找不到记录),这里重新调整:
// GET: 获取删除确认模态框 [HttpGet] [Route("MIDKalorimetar/Delete/{Id:int}")] public async Task<IActionResult> Delete(int Id) { // 直接通过ID查找单个记录 var record = await _db.ParametriMjerila.FindAsync(Id); if (record == null) { return NotFound("未找到要删除的记录"); } // 转换成你的DeleteKalorimetarVM(确保VM包含Id属性) var deleteVM = new DeleteKalorimetarVM { Id = record.Id, // 如果需要显示其他信息,这里补充 }; return PartialView("Delete", deleteVM); } // POST: 执行删除操作 [HttpPost, ActionName("Delete")] [ValidateAntiForgeryToken] public async Task<IActionResult> DeleteConfirmed(int Id) { var record = await _db.ParametriMjerila.FindAsync(Id); if (record == null) { return RedirectToAction(nameof(Index)); } _db.ParametriMjerila.Remove(record); await _db.SaveChangesAsync(); return RedirectToAction(nameof(Index)); }
这里的关键点:
- Get方法只接收单个ID,返回对应记录的删除确认模态框
- Post方法专门处理删除操作,加上
ActionName避免路由冲突,同时启用防伪令牌防止CSRF攻击
2. 修正前端Index.cshtml的按钮参数传递
你之前的问题在于直接传递了数组@Model.Id到URL,导致生成的链接无效(比如Delete/System.Int32[]),现在需要为每个单元格对应的记录生成单独的删除按钮URL:
假设你希望每个单元格旁边都有对应的删除按钮,调整后的表格代码如下:
<tbody style="text-align:center;"> @{ for(int x = 0; x < Model.NajveciBrojElemenata; x++){ <tr id="row-@x"> <!-- 用循环索引作为行ID,避免数组问题 --> <!-- Qi列 --> <td> @Model.Qi.ElementAtOrDefault(x)?.VrijednostKarakteristike @if (dozvoliEdit && Model.Qi.ElementAtOrDefault(x) != null) { <button class="bg-transparent border-0 ms-2" data-toggle="ajax-modal" data-url="@Url.Action("Delete", "MIDKalorimetar", new { Id = Model.Qi[x].Id })"> <img src="/images/deletePng.png" width="20" height="20" title="删除此记录"> </button> } </td> <!-- Qp列 --> <td> @Model.Qp.ElementAtOrDefault(x)?.Opis @if (dozvoliEdit && Model.Qp.ElementAtOrDefault(x) != null) { <button class="bg-transparent border-0 ms-2" data-toggle="ajax-modal" data-url="@Url.Action("Delete", "MIDKalorimetar", new { Id = Model.Qp[x].Id })"> <img src="/images/deletePng.png" width="20" height="20" title="删除此记录"> </button> } </td> <!-- Qs列 --> <td> @Model.Qs.ElementAtOrDefault(x)?.VrijednostKarakteristike @if (dozvoliEdit && Model.Qs.ElementAtOrDefault(x) != null) { <button class="bg-transparent border-0 ms-2" data-toggle="ajax-modal" data-url="@Url.Action("Delete", "MIDKalorimetar", new { Id = Model.Qs[x].Id })"> <img src="/images/deletePng.png" width="20" height="20" title="删除此记录"> </button> } </td> <!-- R列 --> <td> @Model.R.ElementAtOrDefault(x)?.VrijednostKarakteristike @if (dozvoliEdit && Model.R.ElementAtOrDefault(x) != null) { <button class="bg-transparent border-0 ms-2" data-toggle="ajax-modal" data-url="@Url.Action("Delete", "MIDKalorimetar", new { Id = Model.R[x].Id })"> <img src="/images/deletePng.png" width="20" height="20" title="删除此记录"> </button> } </td> <!-- SP列 --> <td> @Model.SP.ElementAtOrDefault(x)?.VrijednostKarakteristike @if (dozvoliEdit && Model.SP.ElementAtOrDefault(x) != null) { <button class="bg-transparent border-0 ms-2" data-toggle="ajax-modal" data-url="@Url.Action("Delete", "MIDKalorimetar", new { Id = Model.SP[x].Id })"> <img src="/images/deletePng.png" width="20" height="20" title="删除此记录"> </button> } </td> </tr> } } </tbody>
如果更倾向于在每行的操作列集中放置所有删除按钮,也可以改成这样:
<td style="width:30%"> @if (dozvoliEdit) { @if (Model.Qi.ElementAtOrDefault(x) != null) { <button class="bg-transparent border-0 me-2" data-toggle="ajax-modal" data-url="@Url.Action("Delete", "MIDKalorimetar", new { Id = Model.Qi[x].Id })" title="删除Qi记录"> <img src="/images/deletePng.png" width="25" height="25"> </button> } @if (Model.Qp.ElementAtOrDefault(x) != null) { <button class="bg-transparent border-0 me-2" data-toggle="ajax-modal" data-url="@Url.Action("Delete", "MIDKalorimetar", new { Id = Model.Qp[x].Id })" title="删除Qp记录"> <img src="/images/deletePng.png" width="25" height="25"> </button> } <!-- 依次添加Qs、R、SP的删除按钮 --> } </td>
3. 确保删除模态框的表单正确发送POST请求
最后检查你的Delete.cshtml部分视图,确保表单使用POST方法并包含防伪令牌,这样才能和后端的Post删除方法匹配:
@model DeleteKalorimetarVM <div class="modal-header"> <h5 class="modal-title">确认删除</h5> <button type="button" class="close" data-dismiss="modal" aria-label="Close"> <span aria-hidden="true">×</span> </button> </div> <div class="modal-body"> <p>确定要删除ID为@Model.Id的记录吗?</p> </div> <div class="modal-footer"> <button type="button" class="btn btn-secondary" data-dismiss="modal">取消</button> <form asp-action="Delete" method="post"> <input type="hidden" asp-for="Id" /> @Html.AntiForgeryToken() <button type="submit" class="btn btn-danger">删除</button> </form> </div>
为什么之前会出现405错误?
- 原Get路由要求5个ID参数,但前端传递的是数组字符串(
System.Int32[]),导致路由不匹配,服务器无法找到对应的Get方法,进而可能返回405(方法不允许) - 原Post方法的参数是
DeleteKalorimetarVM,但如果模态框表单没有正确传递ID,或者HTTP方法不匹配,也会触发405错误
按照上面的步骤调整后,每个删除按钮都会生成正确的单个ID的URL,模态框加载和删除操作都能正常匹配对应的Controller方法,就能解决405问题并实现逐一删除功能了。
内容的提问来源于stack exchange,提问作者loranni
相关产品推荐
相关产品推荐

