ASP.NET Core MVC中复选框更新任务完成状态的ID重复问题
问题原因
你遇到的问题核心是所有任务的隐藏Id输入框都使用了相同的name="Id",当表单提交时,浏览器会将所有同名参数的值打包,但后端模型绑定只会取最后一个值,所以不管点哪个复选框,最终传递的都是循环里最后一个任务的Id。
解决方案
方案1:每个任务对应独立表单(最简单直接)
把<form>标签放到foreach循环内部,让每个任务的复选框和Id输入框都属于自己的表单,提交时只会传递当前任务的参数:
<table> @foreach (ToDoTask todo in Model) { <tr class="theTasks" data-row="row @todo.Id"> <td> <form method="post" asp-action="EditComplete" asp-controller="ToDoTask"> <input type="checkbox" class="roundCheckbox" data-row="row @todo.Id" name="IsCompleted" value="true" onchange="this.form.submit()" @(todo.IsCompleted ? "checked" : "")/> <input type="hidden" name="Id" value="@todo.Id"/> </form> </td> </tr> } </table>
后端代码无需修改,每个表单提交的都是单个任务的Id和IsCompleted状态,模型绑定能正确接收。
方案2:AJAX异步提交(无页面刷新,体验更好)
如果不想每次提交都刷新页面,可通过JavaScript获取当前任务的Id和复选框状态,异步提交到后端:
<table> @foreach (ToDoTask todo in Model) { <tr class="theTasks" data-row="row @todo.Id"> <td> <input type="checkbox" class="roundCheckbox" data-task-id="@todo.Id" @(todo.IsCompleted ? "checked" : "")/> </td> </tr> } </table> @Html.AntiForgeryToken() <script> // 给所有复选框绑定change事件 document.querySelectorAll('.roundCheckbox').forEach(checkbox => { checkbox.addEventListener('change', function() { const taskId = this.dataset.taskId; const isCompleted = this.checked; // 发送POST请求 fetch('/ToDoTask/EditComplete', { method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded', 'RequestVerificationToken': document.querySelector('input[name="__RequestVerificationToken"]').value }, body: `Id=${taskId}&IsCompleted=${isCompleted}` }).then(response => { if (response.ok) { // 可选:提交成功后更新行样式 this.closest('tr').classList.toggle('completed', isCompleted); } }); }); }); </script>
后端代码同样无需修改,AJAX提交的参数格式和原表单一致,能被正确绑定。
内容的提问来源于stack exchange,提问作者lingeringame
相关产品推荐
相关产品推荐

