跳转到主内容
websoft网络软件专家 - 深耕网络技术,打造实用软件!

C#怎么将JSON转为DataTable_C#如何把接口数据填入表格【示例】

JSON字符串不能直接用JsonConvert.DeserializeObject反序列化,因DataTable无默认构造函数;应先解析为JArray或匿名类型再手动构建DataTable,并注意列类型推断、null处理及大小写敏感问题。 JSON字符串直接转DataTable会报错:缺少默认构造函数 用
JsonConvert.DeserializeObject
直接反序列化 JSON 字符串,大概率抛出
ArgumentException: Type 'System.Data.DataTable' does not have a default constructor
。这是因为
DataTable
不是纯数据容器,它带状态、列定义、约束等运行时信息,Newtonsoft.Json 默认不支持直接映射。 别写
JsonConvert.DeserializeObject(json)
—— 这条路走不通 正确做法是先解析成
JArray
或
List>
,再手动构建
DataTable
如果 JSON 是数组结构(如接口返回的 [{ "id":1,"name":"a" }, ...]),才能转;单个对象或嵌套过深的结构需先扁平化 用 JsonConvert.DeserializeAnonymousType + DataTable.Load 填充最稳 这是兼顾类型安全和可控性的常用路径:先用匿名类型“猜”出字段名和类型,再用
DataTable.Load
从
DataReader
导入。比纯反射或手动 AddColumn 更可靠,尤其对 null 值、数字/字符串混排场景。 示例片段:
var json = "[{ \"id\": 1, \"name\": \"Alice\", \"age\": null }]";
var rows = JsonConvert.DeserializeAnonymousType(json, new[] { new { id = 0, name = "", age = (int?)null } });
var dt = new DataTable();
dt.Columns.Add("id", typeof(int));
dt.Columns.Add("name", typeof(string));
dt.Columns.Add("age", typeof(int?));
foreach (var r in rows) {
dt.Rows.Add(r.id, r.name, r.age);
}
注意
age
必须显式声明为
int?
,否则 JSON 中的
null
会导致
InvalidCastException
字段名大小写必须和 JSON key 完全一致(默认区分大小写),否则值为
DBNull.Value
接口返回 List 时,DataTable 列类型容易错判 当后端返回混合类型字段(比如同一字段有时是数字、有时是字符串),
DataTable
的列类型在第一行就定死了。后续类型不匹配的数据会被强制转换或丢弃,不报错但结果异常。 C知道 CSDN推出的一款AI技术问答工具 下载 常见现象:数字列里出现 "N/A" 字符串 → 整列变成
string
,所有数字被转成字符串;或者直接抛
StrongTypingException
解决办法:提前扫描全部数据,用
object.GetType()
统计各字段最宽泛类型(如
string
>
int
>
bool
),再建列 更简单做法:统一设列为
typeof(object)
,业务层再做转换——虽然失去强类型校验,但避免静默失败 DataTable 转 JSON 再转回来?别这么干 有人想“绕开麻烦”:先把
DataTable
用
JsonConvert.SerializeObject(dt)
转成 JSON,再试图反向还原。这会导致列顺序丢失、空值处理混乱、DateTime 格式错乱,且无法恢复原始列类型(比如
DateTime
变成字符串)。 根本问题:JSON 是无 schema 的数据交换格式,
DataTable
是有 schema 的内存表,二者语义不等价 如果必须双向流转,建议用
DataTable.WriteXml()
+
ReadXml()
,或自定义一个含列定义的 JSON 包裹结构 真实项目中,接口数据进表只是中间步骤——真正该花时间设计的是字段映射规则和异常 fallback 策略,不是反复折腾序列化 真正卡住人的从来不是“怎么转”,而是 JSON 结构不稳定、字段类型不一致、空值含义模糊。写死列名和类型前,先用
JObject.Parse(json).SelectToken("data[0]")
看一眼真实样本。

相关文章