You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Newtonsoft反序列化如何实现属性返回空对象而非null

Newtonsoft.Json反序列化null值转空对象实现方案

问题核心

使用Newtonsoft.Json反序列化JSON到C#类实例时,部分引用类型属性在JSON对应值为null时,需要自动初始化为对应类型的空结构实例,而非保留null值。
你之前在PartyIdentification属性上配置的[JsonProperty(DefaultValueHandling = DefaultValueHandling.Populate)]无法生效,原因是:

  • 该配置仅在JSON结构中缺失对应字段时触发默认值填充,字段存在但值为null时不会触发逻辑
  • DefaultValueAttribute本身不支持传入引用类型实例作为默认值,无法直接配置空对象作为填充目标

推荐方案:自定义通用Null转空对象转换器

该方案侵入性最低、灵活度最高,不需要修改原有类的构造逻辑,可精准控制生效范围,是最优选择。

第一步:实现自定义JsonConverter

public class NullToEmptyObjectConverter : JsonConverter
{
    // 仅处理非值类型、非字符串的引用类型
    public override bool CanConvert(Type objectType)
    {
        return !objectType.IsValueType && objectType != typeof(string);
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        // 读取到JSON null值时,通过无参构造生成空实例返回
        if (reader.TokenType == JsonToken.Null)
        {
            // 抽象类、接口等无法实例化的类型兜底返回null,避免运行时报错
            if (objectType.IsAbstract || objectType.IsInterface) return null;
            return Activator.CreateInstance(objectType, nonPublic: true);
        }
        // 非null值走默认反序列化逻辑
        var instance = Activator.CreateInstance(objectType, nonPublic: true);
        serializer.Populate(reader, instance);
        return instance;
    }

    // 禁用序列化阶段的自定义逻辑,不影响原有序列化行为
    public override bool CanWrite => false;
    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }
}

第二步:按需配置生效范围

你可以根据业务需求选择全局生效或者仅指定属性生效:

  • 仅指定属性生效(推荐):给需要做null转空对象的属性添加[JsonConverter]特性,不会影响其他属性的默认反序列化逻辑
public class Party
{
    [JsonConverter(typeof(NullToEmptyObjectConverter))]
    public PartyIdentification PartyIdentification { get; set; }
}

public class PartyIdentification
{
    [JsonProperty(PropertyName = "ID")]
    [JsonConverter(typeof(NullToEmptyObjectConverter))]
    public PartyIdentificationId Id { get; set; }
}
  • 全局生效:反序列化时将转换器加入JsonSerializerSettings,所有匹配CanConvert规则的类型遇到null都会自动生成空实例
var settings = new JsonSerializerSettings
{
    Converters = { new NullToEmptyObjectConverter() }
};
var result = JsonConvert.DeserializeObject<SftiOrderResponse>(jsonContent, settings);

轻量替代方案:构造函数初始化+Null值忽略

如果项目嵌套层级少、逻辑固定,也可以直接在类的无参构造函数中初始化嵌套属性,配合null值忽略配置实现需求,不需要额外写转换器。

实现代码

首先给对应类添加无参构造,初始化嵌套属性:

public class Party
{
    public Party()
    {
        PartyIdentification = new PartyIdentification();
    }

    // 配置null值忽略:遇到JSON null时不覆盖构造函数初始化的实例
    [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
    public PartyIdentification PartyIdentification { get; set; }
}

public class PartyIdentification
{
    public PartyIdentification()
    {
        Id = new PartyIdentificationId();
    }

    [JsonProperty(PropertyName = "ID", NullValueHandling = NullValueHandling.Ignore)]
    public PartyIdentificationId Id { get; set; }
}

注意:必须给属性配置NullValueHandling.Ignore,否则Newtonsoft默认会在遇到JSON null时,把构造函数里初始化的实例覆盖为null。


方案对比

  • 自定义JsonConverter方案:灵活度高,不需要修改原有类定义,可精准控制生效范围,不影响序列化逻辑,适合绝大多数业务场景,为首选方案
  • 构造函数初始化方案:代码简单直观,不需要额外编写转换器,但嵌套层级多时需要重复编写构造初始化逻辑,适合结构简单的固定模型

内容的提问来源于stack exchange,提问作者Don Juan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 21:36:14