jQuery Datatable数据后端JSON反序列化及转DataTable问题
jQuery Datatable自定义Excel导出:JSON反序列化及DataTable转换方案
问题场景
在jQuery Datatable按钮组实现自定义Excel导出功能时,前端将表格数据通过JSON.stringify封装后,通过Ajax传递给后端WebService的ExportToExcel方法,但后端接收JSON字符串后反序列化失败,需要将JSON转换为适配第三方Excel导出工具的DataTable,列名对应THEDATE、E38、E39等字段。
原前端代码
buttons: [ { extend: "collection", text: "Export", buttons: [ { text: 'My Excel', action: function (e, dt, node, config) { exportToExcel(dt); } }, ... ] } ] function exportToExcel(dt) { // var tableRows = dt.rows().data().toArray(); var tableRows = dt.data().toArray(); var blah = JSON.stringify({ TableData: tableRows }); $.ajax({ type: "POST", dataType: "json", contentType: "application/json; charset=utf-8", cache: false, url: "../WebService/ABC.asmx/ExportToExcel", data: JSON.stringify({ TableData: blah }), }).done(function (result) { }).fail(... }
原后端代码
public string ExportToExcel(string TableData) { string JSONresult = string.Empty; //Errors_Counts[] oDict = (JsonConvert.DeserializeObject<Dictionary<string, Errors_Counts[]>>(TableData)).Values.FirstOrDefault(); return JSONresult; }
传递的JSON格式
{"TableData": [ {"THEDATE":"2022-12-10T00:00:00","E38":0,"E39":1,"E40":37,"E41":0,"E42":0}, {"THEDATE":"2022-12-11T00:00:00","E38":0,"E39":0,"E40":20,"E41":0,"E42":0}, ... ] }
解决步骤
第一步:修正前端Ajax数据传递问题
当前前端存在重复JSON序列化的问题:先将tableRows序列化为blah(已成为JSON字符串),Ajax请求时又对blah再次序列化,导致后端拿到的是被转义的无效JSON字符串,这是反序列化失败的核心原因。
修正后的前端代码:
function exportToExcel(dt) { var tableRows = dt.data().toArray(); // 仅做一次序列化,直接将TableData映射到表格数据数组 $.ajax({ type: "POST", dataType: "json", contentType: "application/json; charset=utf-8", cache: false, url: "../WebService/ABC.asmx/ExportToExcel", data: JSON.stringify({ TableData: tableRows }), }).done(function (result) { // 处理导出成功逻辑 }).fail(function(error) { // 处理请求失败逻辑 }); }
第二步:后端反序列化为DataTable/DataSet
使用Newtonsoft.Json(Json.NET)完成反序列化,提供两种方案:
方案一:直接反序列化为DataTable
无需自定义实体类,直接将JSON数组转换为DataTable:
using Newtonsoft.Json; using System.Data; public string ExportToExcel(string TableData) { string JSONresult = string.Empty; try { // 将JSON数组直接反序列化为DataTable DataTable dt = JsonConvert.DeserializeObject<DataTable>(TableData); // 此处可直接使用dt对接第三方Excel导出工具 // ... 你的导出逻辑代码 ... JSONresult = "导出成功"; } catch (Exception ex) { JSONresult = $"反序列化失败:{ex.Message}"; } return JSONresult; }
方案二:先反序列化为实体类数组,再转换为DataTable
如果需要先验证数据结构,可先定义对应实体类:
// 与JSON字段完全匹配的实体类 public class ErrorRecord { public DateTime THEDATE { get; set; } public int E38 { get; set; } public int E39 { get; set; } public int E40 { get; set; } public int E41 { get; set; } public int E42 { get; set; } }
然后在方法中完成反序列化与转换:
using Newtonsoft.Json; using System.Data; using System.Collections.Generic; public string ExportToExcel(string TableData) { string JSONresult = string.Empty; try { // 先反序列化为实体类集合 List<ErrorRecord> records = JsonConvert.DeserializeObject<List<ErrorRecord>>(TableData); // 转换为DataTable(两种方式可选) // 方式1:通过Json.NET间接转换 DataTable dt = JsonConvert.DeserializeObject<DataTable>(JsonConvert.SerializeObject(records)); // 方式2:手动转换(更灵活,可自定义列属性) // DataTable dt = new DataTable(); // dt.Columns.Add("THEDATE", typeof(DateTime)); // dt.Columns.Add("E38", typeof(int)); // dt.Columns.Add("E39", typeof(int)); // dt.Columns.Add("E40", typeof(int)); // dt.Columns.Add("E41", typeof(int)); // dt.Columns.Add("E42", typeof(int)); // foreach(var record in records) // { // dt.Rows.Add(record.THEDATE, record.E38, record.E39, record.E40, record.E41, record.E42); // } // ... 对接第三方Excel导出工具的逻辑 ... JSONresult = "导出成功"; } catch (Exception ex) { JSONresult = $"反序列化失败:{ex.Message}"; } return JSONresult; }
关键注意事项
- 确保后端项目已安装Newtonsoft.Json NuGet包,未安装可通过NuGet控制台执行:
Install-Package Newtonsoft.Json - 前端传递的JSON字段名需与后端DataTable/实体类字段名大小写完全匹配
- 若WebService需返回JSON响应,需在方法上标注
[ScriptMethod(ResponseFormat = ResponseFormat.Json)],或在Web.config中配置JSON响应支持
内容的提问来源于stack exchange,提问作者NoBullMan
相关产品推荐
相关产品推荐

