跳转到主内容
极星编程网:以代码为星,赴技术山海!

C#怎么序列化字典对象_C#如何解决JSON解析报错【避坑】

Dictionary序列化键名丢失或变小写,源于Newtonsoft.Json默认驼峰规则或System.Text.Json启用CamelCase;反序列化数组到Dictionary报错因类型不匹配;value为复杂类型时需确保构造函数和访问性;性能问题多因滥用JToken/JsonElement未及时释放。 Dictionary 序列化后键名丢失或变成小写 默认用
System.Text.Json
序列化
Dictionary
时,键会原样保留;但如果你用的是
Newtonsoft.Json
(即 Json.NET),且没关驼峰命名规则,
"UserName"
这种键会被转成
"userName"
—— 不是数据丢了,是被自动改写了。 实操建议: 确认你用的是哪个库:
System.Text.Json
还是
Newtonsoft.Json
,两者的默认行为完全不同 如果是
Newtonsoft.Json
,检查是否启用了
ContractResolver = new CamelCasePropertyNamesContractResolver()
,它会影响字典键名 想强制保持原始键名?加这个配置:
new JsonSerializerSettings { ContractResolver = new DefaultContractResolver() }
System.Text.Json
默认不碰字典键,但若用了
JsonSerializerOptions.PropertyNamingPolicy = JsonNamingPolicy.CamelCase
,它也会改键名 —— 字典键不是“属性”,但新版(.NET 6+)确实会受此影响 反序列化 JSON 到 Dictionary 时报错 “Cannot deserialize the current JSON array” 常见于把一个 JSON 数组(比如
[{"id":1},{"id":2}]
)直接往
Dictionary
里塞。JSON 数组 ≠ JSON 对象,而
Dictionary
只能对应对象(即
{}
开头的结构)。 实操建议: 先用文本工具或在线 JSON 校验器看一眼原始数据:是
[...]
还是
{...}
?别靠猜测 如果是数组,想转成字典集合,目标类型该是
List>
,不是单个
Dictionary
如果服务端返回格式不固定(有时对象、有时数组),别硬解,先用
JsonElement
或
JToken
做类型探测再分支处理 用
System.Text.Json
时,
JsonSerializer.Deserialize>(json)
遇到数组会直接抛
JsonException
,错误信息里明确写了 “Cannot deserialize the current JSON array” —— 这就是线索 Dictionary 的 value 是复杂类型,反序列化后为 null 典型场景:JSON 里
"data": {"name":"Alice"}
,你定义了
Dictionary
,结果
dict["data"]
是
null
。这不是 bug,是类型擦除导致的反序列化失败。 C知道 CSDN推出的一款AI技术问答工具 下载 实操建议:
Dictionary
是安全兜底方案,所有值都可进,但后续要手动转型 如果坚持用
Dictionary
,必须确保
Person
类型有无参构造函数,且所有字段/属性可被 public 访问(
System.Text.Json
默认不支持 private set / init-only 属性,除非显式配
JsonSerializerOptions.IncludeFields = true
) Newtonsoft.Json 更宽容些,但若
Person
有
[JsonIgnore]
或自定义 converter,也得同步检查 别忽略 nullability:如果 JSON 里
"data"
字段缺失或为
null
,而你的
Person
是非 nullable 引用类型(C# 8+),反序列化可能静默失败或报错 性能差、内存暴涨,只因用了 Dictionary 有人图省事,把整个 JSON 解成
Dictionary
(Newtonsoft)或
Dictionary
(STJ),结果发现 GC 压力大、响应变慢。问题不在字典本身,而在底层 token 持有整个 JSON 文档的引用。 实操建议:
JToken
是“活”的解析树,每次访问子节点都可能触发懒解析,且生命周期难控制;
JsonElement
更轻,但必须在
JsonDocument
有效期内使用,超出就抛
InvalidOperationException: Cannot access child value on a value of type Undefined
真需要灵活读取?优先用
JsonNode
(.NET 6+),它是可变、可序列化的轻量结构,比
JToken
内存友好 如果只是读几个字段,别全量加载:用
JsonDocument.Parse(json).RootElement.GetProperty("user").GetProperty("id").GetInt32()
,避免创建中间字典 特别注意:
JsonDocument
必须
Dispose()
,否则内存泄漏;
JObject.Parse()
同理,别让它活在 long-lived 对象里 最常被跳过的一步:没验证 JSON 字符串本身是否合法,就直接扔给反序列化器。空字符串、BOM 头、HTML 实体编码(如
"
)、意外的换行符,都会让解析器在第一行就跪 —— 先
Trim()
,再
IsValidJson()
(自己写个简版校验),比堆 try-catch 实在得多。

相关文章