猿问

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

我有一个有几个不同类的类,我将这些类中的信息发送给客户,但我不想将它们全部发送出去,所以有些是私有的,有些是[JsonObject(MemberSerialization.OptIn)]旗帜等。


但是,现在我想在需要关闭服务器时每隔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 */ }


}

我尝试了这段代码(即使它已经过时了)但它没有序列化与我的对象相关的对象:


 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);


慕标琳琳
浏览 1376回答 3
3回答

12345678_0001

这应该工作:var settings = new JsonSerializerSettings() { ContractResolver = new MyContractResolver() };var json = JsonConvert.SerializeObject(obj, settings);public class MyContractResolver : Newtonsoft.Json.Serialization.DefaultContractResolver{&nbsp; &nbsp; protected override IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization)&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; var props = type.GetProperties(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .Select(p => base.CreateProperty(p, memberSerialization))&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .Union(type.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;.Select(f => base.CreateProperty(f, memberSerialization)))&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .ToList();&nbsp; &nbsp; &nbsp; &nbsp; props.ForEach(p => { p.Writable = true; p.Readable = true; });&nbsp; &nbsp; &nbsp; &nbsp; return props;&nbsp; &nbsp; }}

小怪兽爱吃肉

它需要.NET 3.5或更高版本。对于我们这些坚持2.0的人......public class ForceJSONSerializePrivatesResolver : Newtonsoft.Json.Serialization.DefaultContractResolver{&nbsp; &nbsp; protected override IList<Newtonsoft.Json.Serialization.JsonProperty> CreateProperties(System.Type type, MemberSerialization memberSerialization)&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; var props = type.GetProperties(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);&nbsp; &nbsp; &nbsp; &nbsp; List<Newtonsoft.Json.Serialization.JsonProperty> jsonProps = new List<Newtonsoft.Json.Serialization.JsonProperty>();&nbsp; &nbsp; &nbsp; &nbsp; foreach( var prop in props )&nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; jsonProps.Add( base.CreateProperty(prop, memberSerialization));&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; foreach( var field in type.GetFields(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance) )&nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; jsonProps.Add ( base.CreateProperty( field, memberSerialization ) );&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; jsonProps.ForEach(p => { p.Writable = true; p.Readable = true; });&nbsp; &nbsp; &nbsp; &nbsp; return jsonProps;&nbsp; &nbsp; }}......似乎有效。

杨魅力

这是一个.linq脚本的完整实现,以防任何人想要使用私有子类进行测试 - 例如,见A有私有子类B.void Main(){&nbsp; &nbsp; var a = A.Test();&nbsp; &nbsp; SerialiseAllFields.Dump(a);}class A{&nbsp; &nbsp; private int PrivField1;&nbsp; &nbsp; private int PrivProp1 { get; set; }&nbsp; &nbsp; private B PrivSubClassField1;&nbsp; &nbsp; public static A Test()&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; return new A { PrivField1 = 1, PrivProp1 = 2, PrivSubClassField1 = B.Test() };&nbsp; &nbsp; }}class B{&nbsp; &nbsp; private int PrivField1;&nbsp; &nbsp; private int PrivProp1 { get; set; }&nbsp; &nbsp; public static B Test()&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; return new B { PrivField1 = 3, PrivProp1 = 4 };&nbsp; &nbsp; }}// Define other methods and classes herepublic static class SerialiseAllFields{&nbsp; &nbsp; public static void Dump(object o, bool indented = true)&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; var settings = new Newtonsoft.Json.JsonSerializerSettings() { ContractResolver = new AllFieldsContractResolver() };&nbsp; &nbsp; &nbsp; &nbsp; if (indented)&nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; settings.Formatting = Newtonsoft.Json.Formatting.Indented;&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; Newtonsoft.Json.JsonConvert.SerializeObject(o, settings).Dump();&nbsp; &nbsp; }}public class AllFieldsContractResolver : Newtonsoft.Json.Serialization.DefaultContractResolver{&nbsp; &nbsp; protected override IList<Newtonsoft.Json.Serialization.JsonProperty> CreateProperties(Type type, Newtonsoft.Json.MemberSerialization memberSerialization)&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; var props = type&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .GetProperties(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .Select(p => base.CreateProperty(p, memberSerialization))&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .Union(type.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .Select(f => base.CreateProperty(f, memberSerialization)))&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .ToList();&nbsp; &nbsp; &nbsp; &nbsp; props.ForEach(p => { p.Writable = true; p.Readable = true; });&nbsp; &nbsp; &nbsp; &nbsp; return props;&nbsp; &nbsp; }}有趣的是,属性的支持字段也是序列化的,即输出为:{&nbsp; "PrivProp1": 2,&nbsp; "PrivField1": 1,&nbsp; "<PrivProp1>k__BackingField": 2,&nbsp; "PrivSubClassField1": {&nbsp; &nbsp; "PrivProp1": 4,&nbsp; &nbsp; "PrivField1": 3,&nbsp; &nbsp; "<PrivProp1>k__BackingField": 4&nbsp; }}
随时随地看视频慕课网APP
我要回答