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

父类标记JsonIgnore后子类序列化仍保留属性的解决方法

解决方案

当子类重写父类的虚拟属性时,父类的[JsonIgnore]特性不会被子类继承,所以序列化时会将子类的ParentProperty视为普通可序列化属性,导致它被输出。以下是两种无需给每个子类添加特性的处理方式:

方法一:全局配置类型信息修改器(推荐)

通过自定义JsonTypeInfoModifier,让所有继承自Parent的类在序列化时自动忽略ParentProperty:

// 定义全局生效的属性忽略规则
public static void IgnoreParentProperty(JsonTypeInfo typeInfo)
{
    if (typeof(Parent).IsAssignableFrom(typeInfo.Type))
    {
        var property = typeInfo.Properties.FirstOrDefault(p => p.Name == nameof(Parent.ParentProperty));
        if (property != null)
        {
            // 设置该属性永远不参与序列化
            property.ShouldSerialize = (obj, value) => false;
        }
    }
}

// 序列化时应用配置
var options = new JsonSerializerOptions
{
    TypeInfoResolver = new DefaultJsonTypeInfoResolver
    {
        Modifiers = { IgnoreParentProperty }
    }
};

var child = new Child
{
    ParentProperty = "ParentProperty",
    ChildProperty = "ChildProperty"
};

Console.WriteLine(JsonSerializer.Serialize(child, options));
// 输出:{"ChildProperty":"ChildProperty"}

这个方案只需一次配置,所有Parent的子类都会自动忽略该属性,完全符合你的需求。

方法二:使用父类属性的显式接口实现

调整父类的属性定义为显式接口实现,这样子类重写时不会覆盖序列化规则:

public interface IParent
{
    string ParentProperty { get; set; }
}

public class Parent : IParent
{
    // 显式实现接口,并用[JsonIgnore]标记
    [JsonIgnore]
    string IParent.ParentProperty { get; set; }

    // 给子类提供可访问的保护属性
    protected virtual string ParentProp
    {
        get => ((IParent)this).ParentProperty;
        set => ((IParent)this).ParentProperty = value;
    }
}

public class Child : Parent
{
    // 用new关键字定义同名属性,内部调用父类的保护属性
    public new string ParentProperty
    {
        get => ParentProp;
        set => ParentProp = value;
    } = "ParentProperty";

    public string ChildProperty { get; set; }
}

此时序列化子类对象时,ParentProperty不会被输出,因为接口的属性已经被标记为忽略,子类的同名属性也不会触发序列化。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 08:52:36