<p>JsonConvert.DeserializeObject 反序列化失败最常见的原因是 JSON 字段名与 C# 属性名不匹配且未配置映射,如 "user_name" 无法自动映射到 UserName;需用 [JsonProperty] 显式指定或启用驼峰适配,同时确保属性有 public get/set、避免 dynamic、正确处理 DateTime 时区及隐式类型转换。</p>
JsonConvert.DeserializeObject 为什么反序列化失败?
最常见的原因是 json 字段名和 c# 属性名不匹配,且没加 [jsonproperty] 或没启用驼峰适配。比如 json 里是 "user_name",c# 类写成 public string username { get; set; },默认就映射不上。
实操建议:
- 确认目标类属性有 public getter/setter(只读属性或字段不行)
- 用
[JsonProperty("user_name")]显式指定源字段名 - 全局启用驼峰兼容:在
JsonSerializerSettings中设CamelCasePropertyNamesContractResolver - 遇到 null 值报错时,给属性加
?(如string?)或设NullValueHandling = NullValueHandling.Ignore
解析嵌套对象或数组时怎么写类型参数?
别硬猜泛型写法——T 必须是具体、可实例化的类型。比如 JSON 是 {"data": [{"id":1},{"id":2}]},就不能写 DeserializeObject<dynamic></dynamic> 然后直接点 .data,因为 dynamic 不保证结构安全,也容易在运行时报 RuntimeBinderException。
实操建议:
- 嵌套对象:定义对应类,如
RootDto含public List<itemdto> Data { get; set; }</itemdto> - 数组顶层:直接用
DeserializeObject<list>>(json)</list> - 不确定结构但需取个别字段:先用
JObject.Parse(json),再用["data"]?.ToObject<list>>()</list> - 避免全用
dynamic,它绕过编译检查,出错晚、难调试
JsonConvert.SerializeObject 输出的 JSON 为啥字段全是大驼峰?
因为 C# 属性默认按 PascalCase 输出,而前端习惯 camelCase。这不是 bug,是默认行为。如果你没配序列化器,SerializeObject 就原样照搬属性名。
实操建议:
- 单次调用:传入带
CamelCasePropertyNamesContractResolver的JsonSerializerSettings - 全局配置(推荐):在启动时设置
JsonConvert.DefaultSettings - 注意:
DefaultSettings是静态的,多线程下要确保初始化一次且不可变 - 如果某几个字段必须保持原样(如 API 协议要求
APIKey),用[JsonProperty("apiKey")]覆盖
DateTime 反序列化时区乱了,字符串格式也不对
JsonConvert 默认把 DateTime 当本地时间处理,且输出格式依赖系统区域设置。JSON 里是 "2024-05-20T12:00:00Z",反序列化后可能变成本地时区的 DateTime 实例,再序列化又丢掉 Z,导致前后端时间偏移。
实操建议:
- 统一用
DateTimeOffset替代DateTime,它自带时区偏移信息 - 序列化时设
DateFormatHandling = DateFormatHandling.IsoDateFormat和DateTimeZoneHandling = DateTimeZoneHandling.Utc - 反序列化前确认 JSON 时间字段是否带时区标识(
Z或+08:00),否则默认按本地时间解析 - 别依赖
ToString()看值——用.Kind和.ToString("o")检查实际内容
最麻烦的其实是隐式类型转换:比如 JSON 里时间是字符串 "2024/05/20",而 C# 属性是 DateTime,这时候会静默失败或抛异常,得靠自定义 JsonConverter 处理。










