C#中如何强制继承JsonIgnore特性?
解决接口属性上JsonIgnore特性无法被实现类继承的问题
问题本质
接口上的序列化特性(如JsonIgnore、JsonPropertyName)默认不会被实现类继承,且JsonIgnoreAttribute是密封类无法通过继承扩展实现强制继承,不过可以通过以下几种方案解决:
方案1:在实现类属性上显式添加特性
这是最直接的解决方案,虽需重复编写特性,但逻辑简单可靠,无需额外配置:
public class InvalidClient : IError { public string Error => "invalid_client"; [JsonIgnore(Condition = JsonIgnoreCondition.Always)] public int StatusCode => (int)HttpStatusCode.Unauthorized; }
方案2:自定义契约解析器强制继承接口特性
编写自定义的DefaultContractResolver,遍历实现类所继承的接口,将接口属性上的序列化特性应用到实现类的对应属性上:
public class InterfaceInheritanceContractResolver : DefaultContractResolver { protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization) { var property = base.CreateProperty(member, memberSerialization); // 遍历当前成员所在类实现的所有接口 foreach (var iface in member.DeclaringType.GetInterfaces()) { var interfaceProperty = iface.GetProperty(member.Name); if (interfaceProperty == null) continue; // 应用接口上的JsonIgnore特性 var ignoreAttr = interfaceProperty.GetCustomAttribute<JsonIgnoreAttribute>(); if (ignoreAttr != null) { property.Ignored = true; property.IgnoreCondition = ignoreAttr.Condition; } // 同时处理JsonPropertyName特性(可选) var propNameAttr = interfaceProperty.GetCustomAttribute<JsonPropertyNameAttribute>(); if (propNameAttr != null && string.IsNullOrEmpty(property.PropertyName)) { property.PropertyName = propNameAttr.Name; } } return property; } }
使用时在序列化配置中指定该解析器:
var serializerOptions = new JsonSerializerOptions { ContractResolver = new InterfaceInheritanceContractResolver() }; // 示例序列化 var json = JsonSerializer.Serialize(new InvalidClient(), serializerOptions);
方案3:改用抽象类替代接口
如果允许调整原有设计,将IError改为抽象类,利用类的特性继承机制(JsonIgnoreAttribute本身已标记Inherited = true),实现特性自动继承:
public abstract class ErrorBase { [JsonPropertyName("error")] public abstract string Error { get; } [JsonIgnore(Condition = JsonIgnoreCondition.Always)] public abstract int StatusCode { get; } } public class InvalidClient : ErrorBase { public override string Error => "invalid_client"; public override int StatusCode => (int)HttpStatusCode.Unauthorized; }
内容的提问来源于stack exchange,提问作者Szyszka947
相关产品推荐
相关产品推荐

