C#怎么生成json字符串_C#如何将实体类序列化为json【技巧】

2次阅读

推荐使用 System.Text.Json 序列化对象,它是 .NET Core 3.0+ 内置高性能 JSON 库,无需额外 NuGet,结果紧凑、安全且 UTF-8 友好;需注意配置差异、循环引用处理、特性迁移(如 [JsonPropertyName])、类型兼容性及 null/ 默认值控制策略。

C#怎么生成 json 字符串_C# 如何将实体类序列化为 json【技巧】

System.Text.Json 序列化对象最稳妥

默认推荐走 System.Text.Json,它是 .NET Core 3.0+ 内置的高性能 JSON 库,无需额外 NuGet,序列化结果紧凑、安全(默认不序列化私有字段和循环引用),且对 UTF-8 友好。

常见错误是直接用 JsonConvert.SerializeObject(来自 Newtonsoft.Json)却没装包,或者混用两个库导致配置不一致。

  • JsonSerializer.Serialize<T>(obj) 是最简调用,适合大多数场景
  • 需要控制格式时加 JsonSerializerOptions:比如 options.WriteIndented = true 美化输出,options.PropertyNamingPolicy = JsonNamingPolicy.CamelCase 转驼峰
  • 若实体含只读属性或私有 setter,需显式启用:options.IgnoreReadOnlyProperties = false(默认为 true
  • 遇到 NotSupportedException: A possible object cycle was detected,不是要关循环检测,而是检查是否真有循环引用;真需要忽略,设 options.ReferenceHandler = ReferenceHandler.Preserve(仅限 .NET 6+)

Newtonsoft.Json 还能用,但要注意版本和配置差异

老项目还在用 Newtonsoft.Json(即 JsonConvert)很常见,它更灵活,但默认行为和 System.Text.Json 不同——比如默认序列化私有字段、支持更多类型、循环引用处理更宽松。

容易踩的坑是:升级到 .NET 6/7 后仍沿用旧习惯,结果发现日期格式变了(System.Text.Json 默认 ISO 8601,Newtonsoft 默认是 "/Date(123)/" 风格),或空字符串被序列化成 null(因 NullValueHandling.Ignore 配置未同步)。

  • JsonConvert.SerializeObject(obj, new JsonSerializerSettings { DateFormatHandling = DateFormatHandling.IsoDateFormat}) 统一日期格式
  • 若想让 string.Empty 不被跳过,确保没设 NullValueHandling.Ignore,或改用 DefaultValueHandling.Ignore
  • 迁移时注意 [JsonProperty("xxx")]System.Text.Json 中对应的是 [JsonPropertyName("xxx")],别漏改特性

序列化失败时先看异常堆栈里的具体类型

报错信息里带 NotSupportedExceptionInvalidOperationException 很常见,但真正卡点往往藏在内层类型上——比如你序列化一个 List<MyClass>,实际崩在 MyClass 里某个 DateTimeOffset? 字段(.NET 5 以下不支持),或某个自定义类没无参构造函数(Newtonsoft 要求,System.Text.Json 默认不要求但反序列化时要)。

  • 把对象先简化:只留 1–2 个基础字段,确认能跑通,再逐步加回
  • 检查字段类型是否在目标框架中受支持(如 System.Drawing.ColorDBNullPointer 类型基本都不行)
  • 若用 ASP.NET Core,默认 MVC 的 JSON 输出走 System.Text.Json,但你手动调 JsonConvert 就可能触发混合行为,导致同一对象在 API 返回和日志打印里格式不一致

别忘了 null 值和默认值的处理逻辑

JSON 字符串里要不要出现 "name": null"count": 0,不是由语言决定的,而是由序列化器的选项和属性上的特性共同控制。很多人以为加了 [JsonIgnore] 就万事大吉,其实 System.Text.Json 和 Newtonsoft 对它的响应方式不同。

  • [JsonIgnore] 在两者中都生效,但 System.Text.Json 还认 [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] 这种细粒度条件(.NET 5+)
  • 想让 int? count = null 不出现在 JSON 里,Newtonsoft 用 NullValueHandling.IgnoreSystem.Text.Json 则需 options.DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull
  • 默认值(如 public bool IsActive {get; set;} = true)不会自动省略,除非加 [DefaultValue(true)] 并配合对应选项(Newtonsoft 支持,System.Text.Json 不支持该特性)

字段级控制比全局选项更可靠,尤其当一个类里有些字段要保留 null、有些要忽略时。别指望靠“统一配一个选项”解决所有问题。

星耀云
版权声明:本站原创文章,由 星耀云 2026-03-25发表,共计2236字。
转载说明:转载本网站任何内容,请按照转载方式正确书写本站原文地址。本站提供的一切软件、教程和内容信息仅限用于学习和研究目的;不得将上述内容用于商业或者非法用途,否则,一切后果请用户自负。本站信息来自网络,版权争议与本站无关。
text=ZqhQzanResources