无[DataContract]标记时Json.NET序列化基类私有字段的问题
问题根因
你自定义的ContractResolver无法序列化基类字段/属性的核心原因是:C# 中Type.GetProperties()和Type.GetFields()方法默认不会返回继承链上层基类定义的私有成员,仅会返回当前类型自身的所有成员、以及基类的公有/受保护成员。要导出全部字段需要递归遍历从当前类型到顶级基类的所有类型,逐一收集成员。
修正后的ContractResolver代码
using System; using System.Collections.Generic; using System.Linq; using System.Reflection; using Newtonsoft.Json; using Newtonsoft.Json.Serialization; public class MyContractResolver : DefaultContractResolver { protected override IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization) { var allMembers = new List<MemberInfo>(); var currentType = type; // 递归遍历整个继承链,直到object类 while (currentType != null && currentType != typeof(object)) { // 收集当前类型的所有属性 allMembers.AddRange(currentType.GetProperties(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance) .Where(p => p.CanRead && p.CanWrite)); // 收集当前类型的所有字段 allMembers.AddRange(currentType.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)); currentType = currentType.BaseType; } // 转换为JsonProperty并去重 var properties = allMembers .Select(m => m is PropertyInfo p ? base.CreateProperty(p, memberSerialization) : base.CreateProperty((FieldInfo)m, memberSerialization)) .Distinct(JsonPropertyComparer.Instance) .ToList(); foreach (var property in properties) { var ignored = ShouldPropertyBeIgnored(property); property.Ignored = ignored; property.Readable = !ignored; property.Writable = !ignored; } return properties; } // 实际包含自定义过滤逻辑 private bool ShouldPropertyBeIgnored(JsonProperty property) => false; }
使用方法
序列化时指定使用自定义的ContractResolver即可:
var derived = new Derived(10); var settings = new JsonSerializerSettings { ContractResolver = new MyContractResolver() }; var serialized = JsonConvert.SerializeObject(derived, settings); Console.WriteLine(serialized);
运行后输出结果为{"_field":10},符合预期序列化要求。
内容的提问来源于stack exchange,提问作者Andrey Golubev
相关产品推荐
相关产品推荐

