C产品如何满足特定用户需求?
- 内容介绍
- 文章标签
- 相关推荐
本文共计1123个文字,预计阅读时间需要5分钟。
`JsonSerializer` 是 .NET Core 3.0 及更高版本内置的高性能 JSON 序列化器,无需额外安装包即可直接使用。若您使用的是 .NET 5、6、7 或 8 等更高版本,优先使用 `JsonSerializer`,而不是 `Newtonsoft.Json` ——除非您依赖它的一些特定老特性(例如动态对象支持、循环引用自动处理或大量保留注释 `JsonProperty` 注解)。
为什么 JsonSerializer 默认不序列化 private 字段或 readonly 属性
它只处理 public 的 get/set 属性,默认忽略字段和只读属性。这是设计使然:强调契约明确、可预测。
- 想序列化私有字段?得加
[JsonInclude](仅限字段,且需是实例字段) - 想序列化只读属性(如
public string Name { get; })?必须配[JsonInclude]+ 确保有初始化值或构造函数赋值 - 反序列化时,
JsonSerializer默认调用无参构造函数;如果类没有无参构造函数,会直接抛NotSupportedException - 若需自定义构造逻辑,得配合
JsonConstructor特性指定目标构造函数
JsonSerializer.Serialize 输出全是小写 key,怎么改成 PascalCase 或自定义命名
默认行为是“原样输出属性名”,但 .NET 的默认 JsonSerializerOptions 启用了 JsonNamingPolicy.CamelCase,所以 UserName 变成 userName。
- 保持 PascalCase:显式设
PropertyNamingPolicy = null - 用下划线分隔(snake_case):需自定义
JsonNamingPolicy,不能直接传字符串 - 个别字段重命名:用
[JsonPropertyName("user_name")],这个特性优先级高于全局策略 - 注意:
[JsonPropertyName]在System.Text.Json中属于System.Text.Json.Serialization命名空间,别漏引用
遇到 System.Text.Json.JsonException: 'The JSON value could not be converted to System.DateTimeOffset'
这是最常踩的坑之一:日期类型在 JSON 中本就是字符串格式(如 "2025-08-01T12:00:00+08:00"),但 JsonSerializer 对格式极其严格,默认只认 ISO 8601 标准子集,且不自动容忍空格、多余时区符号或非标准格式(比如 "2025/08/01")。
- 确保输入 JSON 中的日期字段确实是标准 ISO 格式;否则反序列化必失败
- 自定义解析逻辑?写一个
JsonConverter<DateTimeOffset>,重写Read方法,用DateTimeOffset.TryParseExact多试几种格式 - 序列化时控制输出格式?在 converter 的
Write方法里手动格式化,不要依赖ToString()默认行为 - 别试图用
string临时绕过——这会让类型语义丢失,后续维护成本陡增
嵌套对象反序列化失败,但 JSON 看起来完全合法
常见现象是反序列化后子对象为 null,即使 JSON 字符串里明明有对应字段。根本原因往往不是语法错,而是类型契约不匹配。
- 检查嵌套类是否是
public——JsonSerializer拒绝序列化/反序列化internal或private类型 - 确认嵌套属性的类型声明和 JSON 实际结构一致:比如 JSON 给的是
"items": ["a","b"],但 C# 属性声明为public List<Item> Items { get; set; },就会因类型不匹配而跳过 - JSON 里字段名大小写和 C# 属性名对不上?默认策略是 camelCase,但若后端返回 PascalCase 字段(如
"UserName"),而你没配[JsonPropertyName],就无法绑定 - 使用
JsonSerializerOptions.UnknownTypeHandling = JsonUnknownTypeHandling.JsonElement可临时捕获未知结构,但只是调试手段,不能长期替代契约定义
真正麻烦的从来不是“怎么让 JSON 跑起来”,而是“怎么让类型定义和 API 文档、前后端约定、历史数据格式稳稳咬合”。JsonSerializer 的严格性不是缺陷,是提醒你:契约模糊的地方,迟早要出问题。
本文共计1123个文字,预计阅读时间需要5分钟。
`JsonSerializer` 是 .NET Core 3.0 及更高版本内置的高性能 JSON 序列化器,无需额外安装包即可直接使用。若您使用的是 .NET 5、6、7 或 8 等更高版本,优先使用 `JsonSerializer`,而不是 `Newtonsoft.Json` ——除非您依赖它的一些特定老特性(例如动态对象支持、循环引用自动处理或大量保留注释 `JsonProperty` 注解)。
为什么 JsonSerializer 默认不序列化 private 字段或 readonly 属性
它只处理 public 的 get/set 属性,默认忽略字段和只读属性。这是设计使然:强调契约明确、可预测。
- 想序列化私有字段?得加
[JsonInclude](仅限字段,且需是实例字段) - 想序列化只读属性(如
public string Name { get; })?必须配[JsonInclude]+ 确保有初始化值或构造函数赋值 - 反序列化时,
JsonSerializer默认调用无参构造函数;如果类没有无参构造函数,会直接抛NotSupportedException - 若需自定义构造逻辑,得配合
JsonConstructor特性指定目标构造函数
JsonSerializer.Serialize 输出全是小写 key,怎么改成 PascalCase 或自定义命名
默认行为是“原样输出属性名”,但 .NET 的默认 JsonSerializerOptions 启用了 JsonNamingPolicy.CamelCase,所以 UserName 变成 userName。
- 保持 PascalCase:显式设
PropertyNamingPolicy = null - 用下划线分隔(snake_case):需自定义
JsonNamingPolicy,不能直接传字符串 - 个别字段重命名:用
[JsonPropertyName("user_name")],这个特性优先级高于全局策略 - 注意:
[JsonPropertyName]在System.Text.Json中属于System.Text.Json.Serialization命名空间,别漏引用
遇到 System.Text.Json.JsonException: 'The JSON value could not be converted to System.DateTimeOffset'
这是最常踩的坑之一:日期类型在 JSON 中本就是字符串格式(如 "2025-08-01T12:00:00+08:00"),但 JsonSerializer 对格式极其严格,默认只认 ISO 8601 标准子集,且不自动容忍空格、多余时区符号或非标准格式(比如 "2025/08/01")。
- 确保输入 JSON 中的日期字段确实是标准 ISO 格式;否则反序列化必失败
- 自定义解析逻辑?写一个
JsonConverter<DateTimeOffset>,重写Read方法,用DateTimeOffset.TryParseExact多试几种格式 - 序列化时控制输出格式?在 converter 的
Write方法里手动格式化,不要依赖ToString()默认行为 - 别试图用
string临时绕过——这会让类型语义丢失,后续维护成本陡增
嵌套对象反序列化失败,但 JSON 看起来完全合法
常见现象是反序列化后子对象为 null,即使 JSON 字符串里明明有对应字段。根本原因往往不是语法错,而是类型契约不匹配。
- 检查嵌套类是否是
public——JsonSerializer拒绝序列化/反序列化internal或private类型 - 确认嵌套属性的类型声明和 JSON 实际结构一致:比如 JSON 给的是
"items": ["a","b"],但 C# 属性声明为public List<Item> Items { get; set; },就会因类型不匹配而跳过 - JSON 里字段名大小写和 C# 属性名对不上?默认策略是 camelCase,但若后端返回 PascalCase 字段(如
"UserName"),而你没配[JsonPropertyName],就无法绑定 - 使用
JsonSerializerOptions.UnknownTypeHandling = JsonUnknownTypeHandling.JsonElement可临时捕获未知结构,但只是调试手段,不能长期替代契约定义
真正麻烦的从来不是“怎么让 JSON 跑起来”,而是“怎么让类型定义和 API 文档、前后端约定、历史数据格式稳稳咬合”。JsonSerializer 的严格性不是缺陷,是提醒你:契约模糊的地方,迟早要出问题。

