如何用jQuery、AJAX和ASP.NET MVC5保存多选复选框?求解决报错
问题:DataTable选中复选框数据通过AJAX保存到SQL数据库失败(ASP.NET MVC5 + jQuery)
我尝试使用jQuery、AJAX和ASP.NET MVC5将DataTable中选中的复选框数据保存到SQL数据库,但执行过程中出现错误,以下是我的原始代码,请求帮助解决:
原始HTML代码
<table id="example" class="display select" width="100%" cellspacing="0"> <thead> <tr> <th><input type="checkbox" name="select_all" value="1" id="example-select-all" /></th> <th>EmpID</th> <th>Employes Name</th> <th>Basic Salary</th> <th>Tax</th> <th>Total Allowance</th> <th>Total Deductions</th> <th>Gross Salary</th> <th>Taxable Income</th> <th>Net Salary</th> </tr> </thead> </table>
原始jQuery脚本
<script> $(document).ready(function () { $(document).ready(function () { var table = $('#example').DataTable({ 'columnDefs': [{ 'targets': 0, 'searchable': false, 'orderable': false, 'className': 'dt-body-center', 'render': function (data, type, full, meta) { return '<input type="checkbox" name="id[]" value="' + $('<div/>').text(data).html() + '">'; } }], 'order': [[1, 'asc']], "ajax": { "url": '/Payroll/GetEmplo', "type": 'GET', "datatype": 'JSON', className: 'select-checkbox', targets: 0, orderable: false, }, "columns": [ { data: "" }, { data: "EmpID" }, { data: "EmpName" }, { data: "BasicSalary" }, { data: "Tax" }, { data: "Total_Allowance" }, { data: "Total_Deduction" }, { data: "GrossSalary" }, { data: "TaxableIncome" }, { data: "NetSalary" }, ], }); // Handle click on "Select all" control $('#example-select-all').on('click', function () { var rows = table.rows({ 'search': 'applied' }).nodes(); $('input[type="checkbox"]', rows).prop('checked', this.checked); }); // Handle click on checkbox to set state of "Select all" control $('#example tbody').on('change', 'input[type="checkbox"]', function () { if (!this.checked) { var el = $('#example-select-all').get(0); if (el && el.checked && ('indeterminate' in el)) { el.indeterminate = true; } } }); $('#SaveSalaryy').on('click', function () { var myCheckboxes = []; $('input:checkbox.example-select-all').each(function () { if ($(this).prop('checked')) { myCheckboxes.push($(this).attr("value")); } }); var mySelectedValue = $('#example-select-all').find(":selected").text(); var json = { myCheckboxes: myCheckboxes, mySelectedValue: mySelectedValue }; var options = {}; options.url = '/Payroll/SaveSalaryy'; options.type = "POST"; options.data = { "json": JSON.stringify(json) }; options.dataType = "JSON"; options.success = function (msg) { alert(msg); }; options.error = function () { alert("Error while deleting the records!"); }; $.ajax(options); }); $('#frm-example').on('submit', function (e) { var form = this; table.$('input[type="checkbox"]').each(function () { if (!$.contains(document, this)) { if (this.checked) { $(form).append( $('<input>') .attr('type', 'hidden') .attr('name', this.name) .val(this.value) ); } } }); }); }); </script>
原始控制器代码
[HttpPost] public JsonResult SaveSalaryy(string json) { var serializer = new JavaScriptSerializer(); dynamic jsondata = serializer.Deserialize(json, typeof(object)); var checboxValues = jsondata["myCheckboxes"]; var mySelectedValue = jsondata["mySelectedValue"]; DB.Calcs.Add(mySelectedValue); DB.SaveChanges(); return mySelectedValue(); }
错误分析与修复方案
核心错误点
- jQuery重复初始化:嵌套两层
$(document).ready,导致逻辑执行异常 - 复选框值为空:DataTable渲染复选框时,
data为空(第一列data:""),无法获取员工ID作为复选框值 - 选中数据获取错误:选择器仅匹配全选框,无法获取行内选中的复选框;复选框无
selected属性,相关逻辑完全无效 - AJAX提交格式错误:将JSON字符串作为表单参数传递,后端手动反序列化易出错,且未设置正确的
contentType - 控制器逻辑错误:非法调用动态变量作为方法;直接将字符串添加到实体集合,不符合实体类要求;未处理多选中的员工ID数组
修复后的代码
1. 修复后的jQuery脚本
<script> $(document).ready(function () { var table = $('#example').DataTable({ columnDefs: [{ targets: 0, searchable: false, orderable: false, className: 'dt-body-center', render: function (data, type, full, meta) { // 用员工ID作为复选框value return `<input type="checkbox" name="id[]" value="${full.EmpID}">`; } }], order: [[1, 'asc']], ajax: { url: '/Payroll/GetEmplo', type: 'GET', dataType: 'JSON' }, columns: [ { data: null }, // 第一列无绑定数据,用于渲染复选框 { data: "EmpID" }, { data: "EmpName" }, { data: "BasicSalary" }, { data: "Tax" }, { data: "Total_Allowance" }, { data: "Total_Deduction" }, { data: "GrossSalary" }, { data: "TaxableIncome" }, { data: "NetSalary" } ] }); // 全选/取消全选逻辑 $('#example-select-all').on('click', function () { var rows = table.rows({ search: 'applied' }).nodes(); $('input[type="checkbox"]', rows).prop('checked', this.checked); }); // 单个复选框点击,更新全选框状态 $('#example tbody').on('change', 'input[type="checkbox"]', function () { var allChecked = table.$('input[type="checkbox"]').length === table.$('input[type="checkbox"]:checked').length; var noneChecked = table.$('input[type="checkbox"]:checked').length === 0; var el = $('#example-select-all').get(0); if (allChecked) { el.checked = true; el.indeterminate = false; } else if (noneChecked) { el.checked = false; el.indeterminate = false; } else { el.indeterminate = true; } }); // 保存按钮点击事件 $('#SaveSalaryy').on('click', function () { // 获取所有选中的复选框值(EmpID) var selectedEmpIDs = []; table.$('input[type="checkbox"]:checked').each(function () { selectedEmpIDs.push($(this).val()); }); if (selectedEmpIDs.length === 0) { alert("请选择要保存的员工"); return; } $.ajax({ url: '/Payroll/SaveSalaryy', type: 'POST', contentType: 'application/json', // 关键:设置请求内容类型为JSON data: JSON.stringify(selectedEmpIDs), dataType: 'JSON', success: function (msg) { alert(msg.message); // 可选:刷新表格 table.ajax.reload(); }, error: function (xhr) { alert(`保存失败:${xhr.responseText}`); } }); }); }); </script>
2. 修复后的控制器代码
首先创建响应模型(可选,也可直接返回字符串):
public class SaveResponse { public bool Success { get; set; } public string Message { get; set; } }
修改控制器方法:
[HttpPost] public JsonResult SaveSalaryy(List<int> selectedEmpIDs) { try { foreach (var empId in selectedEmpIDs) { // 根据EmpID获取员工信息(假设员工实体类为Employee) var employee = DB.Employees.FirstOrDefault(e => e.EmpID == empId); if (employee == null) continue; // 创建薪资计算实体(假设目标表实体类为Calc) var calc = new Calc { EmpID = empId, EmpName = employee.EmpName, BasicSalary = employee.BasicSalary, Tax = employee.Tax, Total_Allowance = employee.Total_Allowance, Total_Deduction = employee.Total_Deduction, GrossSalary = employee.GrossSalary, TaxableIncome = employee.TaxableIncome, NetSalary = employee.NetSalary, CreatedDate = DateTime.Now }; DB.Calcs.Add(calc); } DB.SaveChanges(); return Json(new SaveResponse { Success = true, Message = "保存成功" }); } catch (Exception ex) { // 可选:添加日志记录 return Json(new SaveResponse { Success = false, Message = $"保存失败:{ex.Message}" }); } }
额外说明
- 确保
GetEmplo返回的JSON字段名与DataTable的columns.data完全匹配(如Total_Allowance不要写成TotalAllowance) - 若
EmpID为字符串类型,将控制器的List<int>改为List<string> - 建议添加异常日志,方便后续排查问题
- 若不需要表单提交逻辑,可删除
$('#frm-example').on('submit'...)部分
内容的提问来源于stack exchange,提问作者Adane Tesfaye
相关产品推荐
相关产品推荐

