C#如何序列化和反序列化Nullable类型

23次阅读

C#中序列化反序列化NULLable类型无本质障碍,主流序列化器均原生支持,但需注意System.Text.json默认良好、Newtonsoft.json需避免NullValueHandling.Ignore、xmlSerializer需标记IsNullable=true。

C#如何序列化和反序列化Nullable类型

C# 中序列化和反序列化 Nullable(如 int?DateTime?)类型本身没有特殊障碍,.net 的主流序列化器(如 System.Text.JsonNewtonsoft.JsonXmlSerializerBinaryFormatter(已弃用))都原生支持。关键在于理解其行为逻辑,并注意常见陷阱。

System.Text.Json 默认支持良好

从 .NET Core 3.0 起,System.Text.Json 对可空值类型有开箱即用的支持:

  • 序列化时,null 值会被转为 JSON 的 null;非空值按对应类型正常输出(如 42"2023-01-01T00:00:00")。
  • 反序列化时,JSON 的 null 会正确映射为 T?null;数值或字符串会尝试转换并赋值。
  • 无需额外配置,只要属性声明为 int?DateTime? 即可。

示例:

public class Person { public String Name { get; set; } = “Alice”; public int? Age { get; set; } }
var p = new Person { Age = null };
string json = JsonSerializer.Serialize(p); // {“Name”:”Alice”,”Age”:null}

Newtonsoft.Json 需注意默认设置

Newtonsoft.Json(Json.NET)同样支持可空类型,但若使用了自定义 JsonSerializerSettings,需确认以下两点:

  • 不要启用 NullValueHandling.Ignore(除非你明确希望跳过整个属性)——它会让 int? null 在序列化时不输出该字段,导致反序列化时使用默认值(如 0),而非 null
  • 若启用了 DefaultValueHandling.Ignore,且为可空类型指定了 [DefaultValue(null)],也要留意是否影响预期行为。

推荐保持默认设置,或显式指定:
new JsonSerializerSettings { NullValueHandling = NullValueHandling.include }

XML 序列化需处理 xsi:nil 属性

XmlSerializer 处理可空类型时,会生成符合 XSI 规范的 xsi:nil="true" 属性来表示 null:

这要求目标类属性必须用 [XmlElement(IsNullable = true)] 标记,否则反序列化时可能失败或忽略该字段:

public class Person { [XmlElement(IsNullable = true)] public int? Age { get; set; } }

自定义转换器仅在特殊需求时才需要

绝大多数场景下无需自定义逻辑。只有当你需要改变默认行为时才考虑,例如:

  • int?null 序列化为特定字符串(如 "N/A");
  • 兼容旧系统,将缺失字段统一视为 null 而非默认值;
  • DateTime? 的 null 值做特殊时间戳标记。

此时可继承 JsonConverter 并重写 Read/Write 方法,再通过 JsonSerializerOptions.Converters.Add(...) 注册。

text=ZqhQzanResources