多Post表单提交按钮关联错误:第二个表单始终触发第一个表单
我之前也碰到过几乎一模一样的问题!ASP.NET Core的Razor标签助手在循环渲染多个表单时,偶尔会因为上下文混乱生成错误的formaction,导致按钮绑定到错误的表单请求上,尤其是你这种批量生成删除表单的场景。给你几个亲测有效的解决思路:
1. 给表单加唯一ID,让按钮明确关联所属表单
这是最直接的解决方案——给每个表单分配一个唯一的id,然后让提交按钮通过form属性绑定到这个ID,彻底避免按钮“找错表单”的情况:
<form id="delete-form-@item.Id" asp-controller="Mentor" asp-action="DeleteAchievement" asp-route-id="@item.Id" method="post"> <button type="submit" class="btn btn-primary" form="delete-form-@item.Id">Delete</button> </form>
这样生成的HTML里,按钮会明确指向对应ID的表单,不会再乱继承其他表单的formaction。
2. 移除按钮上多余的asp-route-id
你的按钮上额外加了asp-route-id="@item.Id",这其实是画蛇添足——表单已经通过asp-route-id传递了参数,按钮上的这个标签助手反而会干扰formaction的生成逻辑,直接删掉就好。
3. 检查DOM结构是否有未闭合的标签
有时候这种表单混乱的问题,根源是前面的HTML标签没正确闭合,导致DOM结构错位,Razor渲染时上下文出错。可以打开浏览器开发者工具的「Elements」面板,逐个检查每个<form>标签是否都正确闭合,有没有嵌套或错位的情况。
4. 手动指定表单Action(备选方案)
如果标签助手还是抽风,直接放弃标签助手,手动写死表单的action属性,同时记得手动添加防伪令牌(因为你的控制器加了[ValidateAntiForgeryToken]):
<form action="/Mentor/DeleteAchievement/@item.Id" method="post"> @Html.AntiForgeryToken() <button type="submit" class="btn btn-primary">Delete</button> </form>
这种方式虽然不够“优雅”,但胜在绝对可靠,不会出现标签助手的上下文问题。
我当时就是因为循环里的表单没有唯一标识,按钮默认绑定了最近的表单,但Razor渲染时因为循环上下文的问题,把前面表单的Action绑定到了后面的按钮上,用第一个方法加了表单ID和按钮的form属性后就彻底解决了。
内容的提问来源于stack exchange,提问作者J.Kirk.

