You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用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();
}

错误分析与修复方案

核心错误点

  1. jQuery重复初始化:嵌套两层$(document).ready,导致逻辑执行异常
  2. 复选框值为空:DataTable渲染复选框时,data为空(第一列data:""),无法获取员工ID作为复选框值
  3. 选中数据获取错误:选择器仅匹配全选框,无法获取行内选中的复选框;复选框无selected属性,相关逻辑完全无效
  4. AJAX提交格式错误:将JSON字符串作为表单参数传递,后端手动反序列化易出错,且未设置正确的contentType
  5. 控制器逻辑错误:非法调用动态变量作为方法;直接将字符串添加到实体集合,不符合实体类要求;未处理多选中的员工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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.08 04:31:06