16

How can I customize Json.NET to serialize private members and NOT serialize public readonly properties (without using attributes).

I've had a stab around at creating a custom IContractResolver but am a bit lost.

4

2 回答 2

12

对于部分答案,弄乱 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 异常。

于 2013-02-08T20:43:53.157 回答
4

作为对Chris 的回答DefaultMemberSearchFlags属性 onDefaultContractResolver 自版本 6 起已弃用。尽管弃用消息说了什么,但我相信您也需要覆盖该CreateProperties方法,就像LB 解释的那样。

此方法使您可以完全控制,包括排除只读属性:

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);
    }           
}
于 2014-09-25T13:56:54.003 回答