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