如何用Json.NET按接口定义序列化对象,支持非原始类型属性
C# 基于接口限定JSON序列化属性范围(支持嵌套非原始类型)
需求背景
需要基于接口定义完成对象的JSON序列化,仅保留接口内声明的所有属性,忽略实现类的自有属性,同时支持接口定义的复杂类型、嵌套对象的完整序列化。
示例代码定义
public interface IInterface { SubClass Sub { get; set; } int A { get; set; } } public class Class : IInterface { public SubClass Sub { get; set; } = new(); public int A { get; set; } = 1; public int B { get; set; } = 1; } public class SubClass { public int C { get; set; } = 2; }
期望序列化效果
对Class类的实例序列化时,输出内容如下,仅保留IInterface定义的Sub、A属性,忽略类自有属性B,同时嵌套的Sub属性完整序列化:
{"Sub":{"C":2},"A":1}
实现方案
通过自定义DefaultContractResolver实现属性筛选,代码如下:
public class InterfaceContractResolver : DefaultContractResolver { private readonly Type[] _interfaceTypes; private readonly ConcurrentDictionary<Type, Type> _typeToSerializeMap; public InterfaceContractResolver(params Type[] interfaceTypes) { _interfaceTypes = interfaceTypes; _typeToSerializeMap = new ConcurrentDictionary<Type, Type>(); } protected override IList<JsonProperty> CreateProperties( Type type, MemberSerialization memberSerialization) { var typeToSerialize = _typeToSerializeMap.GetOrAdd( type, t => _interfaceTypes.FirstOrDefault( it => it.IsAssignableFrom(t)) ?? t); var props = base.CreateProperties(typeToSerialize, memberSerialization); // 标记所有属性为不忽略 foreach (var prop in props) { prop.Ignored = false; } return props; } }
使用方式
序列化时在JsonSerializerSettings中指定自定义的ContractResolver,传入要作为序列化范围限定的接口类型即可:
var target = new Class(); string jsonResult = JsonConvert.SerializeObject(target, new JsonSerializerSettings { ContractResolver = new InterfaceContractResolver(typeof(IInterface)) });
内容的提问来源于stack exchange,提问作者Vic
相关产品推荐
相关产品推荐

