父类标记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
相关产品推荐
相关产品推荐

