【发布时间】:2012-04-17 10:27:54
【问题描述】:
如何自定义 Json.NET 以序列化私有成员而不序列化公共只读属性(不使用属性)。
我曾尝试过创建自定义 IContractResolver,但有点迷茫。
【问题讨论】:
如何自定义 Json.NET 以序列化私有成员而不序列化公共只读属性(不使用属性)。
我曾尝试过创建自定义 IContractResolver,但有点迷茫。
【问题讨论】:
对于部分答案,弄乱 DefaultContractResolver.DefaultMembersSearchFlags 可以让它包含私人的东西:
Newtonsoft.Json.JsonSerializerSettings jss = new Newtonsoft.Json.JsonSerializerSettings();
if (includePrivateMembers)
{
Newtonsoft.Json.Serialization.DefaultContractResolver dcr = new Newtonsoft.Json.Serialization.DefaultContractResolver();
dcr.DefaultMembersSearchFlags |= System.Reflection.BindingFlags.NonPublic;
jss.ContractResolver = dcr;
}
return Newtonsoft.Json.JsonConvert.SerializeObject(o, jss);
似乎对很多对象都有效,但其中一些似乎会产生 CLR 异常。
【讨论】:
响应Chris' answer,DefaultMemberSearchFlags 属性位于DefaultContractResolver was deprecated as of version 6。尽管弃用消息说了什么,我相信您也需要覆盖CreateProperties 方法,例如L.B explains。
此方法让您可以完全控制,包括排除只读属性:
class PrivateContractResolver : DefaultContractResolver
{
protected override List<MemberInfo> GetSerializableMembers(Type objectType)
{
var flags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;
MemberInfo[] fields = objectType.GetFields(flags);
return fields
.Concat(objectType.GetProperties(flags).Where(propInfo => propInfo.CanWrite))
.ToList();
}
protected override IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization)
{
return base.CreateProperties(type, MemberSerialization.Fields);
}
}
【讨论】: