.NET调用带输出参数的存储过程 将DataTable与返回值序列化为JSON
问题根因
你当前序列化结果不符合预期的核心原因是:Newtonsoft.Json 默认不会将 DataRow 对象转换为业务侧需要的列名-值形式的JSON结构,而是会序列化 DataRow 自身的内部属性,输出冗余且不符合预期的内容。
下面提供两种可直接落地的解决方案:
方案1:直接使用DataTable作为属性类型(最简方案)
Newtonsoft.Json 原生支持 DataTable 类型的序列化,会自动将表格转换为「列名为键、行值为值」的对象数组,无需额外转换逻辑。
代码修改:
- 调整
MyClass的属性类型:
public class MyClass { // 把原来的IEnumerable<DataRow>改为DataTable public System.Data.DataTable Transactions { get; set; } public int ReturnCode { get; set; } public string ReturnString { get; set; } }
- 修改赋值逻辑,无需调用
AsEnumerable():
MyClass myClass = new MyClass(); // 直接赋值DataTable即可 myClass.Transactions = dataTable; myClass.ReturnCode = returnCode; myClass.ReturnString = returnStr; // 直接序列化即可得到符合预期的结果 jsonResult = Newtonsoft.Json.JsonConvert.SerializeObject(myClass);
方案2:转换为字典集合(无需保留DataTable元数据时使用)
如果你不想在序列化结果中包含DataTable的结构元数据,只需要纯行数据,可以将DataTable转换为字典集合再序列化:
代码修改:
- 新增DataTable转字典集合的扩展方法:
public static class DataTableExtensions { public static IEnumerable<Dictionary<string, object>> ToJsonFriendlyList(this DataTable dt) { return dt.AsEnumerable().Select(row => dt.Columns.Cast<DataColumn>().ToDictionary( col => col.ColumnName, // 处理数据库NULL值,避免序列化为DBNull类型 col => row[col] == DBNull.Value ? null : row[col] ) ); } }
- 调整
MyClass的属性类型:
public class MyClass { public IEnumerable<Dictionary<string, object>> Transactions { get; set; } public int ReturnCode { get; set; } public string ReturnString { get; set; } }
- 调用扩展方法赋值:
MyClass myClass = new MyClass(); myClass.Transactions = dataTable.ToJsonFriendlyList(); myClass.ReturnCode = returnCode; myClass.ReturnString = returnStr; jsonResult = Newtonsoft.Json.JsonConvert.SerializeObject(myClass);
注意事项
两种方案默认都会处理存储过程返回的动态列结构,无需提前定义实体类,适配你存储过程返回不同列的场景。
内容的提问来源于stack exchange,提问作者SoftwareDveloper
相关产品推荐
相关产品推荐

