JSON.Net:强制所有私有字段和子类中的所有字段的序列化

我有一个类与几个不同的类,我把这些类的信息发送到客户端,但我不想全部发送出去,所以有些是私人的,一些有[JsonObject(MemberSerialization.OptIn)]标志等。

但是,现在我想要做所有这些对象的备份,当我需要closures服务器和每12小时(我不想使用数据库),所以我想要做的(如果可能的话)是强制JSON .Net Serializer来转换对象和属于该对象的所有对象。

例如:

 class Foo { public int Number; private string name; private PrivateObject po = new PrivateObject(); public string ToJSON() { /* Serialize my public field, my property and the object PrivateObject */ } } 

我试过这个代码(尽pipe它已经过时了),但是它没有序列化与我的对象相关的对象:

  Newtonsoft.Json.JsonSerializerSettings jss = new Newtonsoft.Json.JsonSerializerSettings(); Newtonsoft.Json.Serialization.DefaultContractResolver dcr = new Newtonsoft.Json.Serialization.DefaultContractResolver(); dcr.DefaultMembersSearchFlags |= System.Reflection.BindingFlags.NonPublic; jss.ContractResolver = dcr; return Newtonsoft.Json.JsonConvert.SerializeObject(this, jss); 

这应该工作:

 var settings = new JsonSerializerSettings() { ContractResolver = new MyContractResolver() }; var json = JsonConvert.SerializeObject(obj, settings); 

 public class MyContractResolver : Newtonsoft.Json.Serialization.DefaultContractResolver { protected override IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization) { var props = type.GetProperties(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance) .Select(p => base.CreateProperty(p, memberSerialization)) .Union(type.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance) .Select(f => base.CreateProperty(f, memberSerialization))) .ToList(); props.ForEach(p => { p.Writable = true; p.Readable = true; }); return props; } } 

@ LB的回答非常好。 但是…它需要.NET 3.5或更高版本。

对于我们这些坚持2.0的人

 public class ForceJSONSerializePrivatesResolver : Newtonsoft.Json.Serialization.DefaultContractResolver { protected override IList<Newtonsoft.Json.Serialization.JsonProperty> CreateProperties(System.Type type, MemberSerialization memberSerialization) { var props = type.GetProperties(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance); List<Newtonsoft.Json.Serialization.JsonProperty> jsonProps = new List<Newtonsoft.Json.Serialization.JsonProperty>(); foreach( var prop in props ) { jsonProps.Add( base.CreateProperty(prop, memberSerialization)); } foreach( var field in type.GetFields(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance) ) { jsonProps.Add ( base.CreateProperty( field, memberSerialization ) ); } jsonProps.ForEach(p => { p.Writable = true; p.Readable = true; }); return jsonProps; } } 

似乎工作。

真棒谢谢@LB以下是.linq脚本中的完整实现,以防任何人想要使用私有子类进行testing – 例如,请参阅A有私有子类B.

 void Main() { var a = A.Test(); SerialiseAllFields.Dump(a); } class A { private int PrivField1; private int PrivProp1 { get; set; } private B PrivSubClassField1; public static A Test() { return new A { PrivField1 = 1, PrivProp1 = 2, PrivSubClassField1 = B.Test() }; } } class B { private int PrivField1; private int PrivProp1 { get; set; } public static B Test() { return new B { PrivField1 = 3, PrivProp1 = 4 }; } } // Define other methods and classes here public static class SerialiseAllFields { public static void Dump(object o, bool indented = true) { var settings = new Newtonsoft.Json.JsonSerializerSettings() { ContractResolver = new AllFieldsContractResolver() }; if (indented) { settings.Formatting = Newtonsoft.Json.Formatting.Indented; } Newtonsoft.Json.JsonConvert.SerializeObject(o, settings).Dump(); } } public class AllFieldsContractResolver : Newtonsoft.Json.Serialization.DefaultContractResolver { protected override IList<Newtonsoft.Json.Serialization.JsonProperty> CreateProperties(Type type, Newtonsoft.Json.MemberSerialization memberSerialization) { var props = type .GetProperties(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance) .Select(p => base.CreateProperty(p, memberSerialization)) .Union(type.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance) .Select(f => base.CreateProperty(f, memberSerialization))) .ToList(); props.ForEach(p => { p.Writable = true; p.Readable = true; }); return props; } } 

有趣的是,属性的​​后台字段也是序列化的,即输出是:

 { "PrivProp1": 2, "PrivField1": 1, "<PrivProp1>k__BackingField": 2, "PrivSubClassField1": { "PrivProp1": 4, "PrivField1": 3, "<PrivProp1>k__BackingField": 4 } }