使用ReferenceLoopHandling.Ignore序列化依赖于循环的ISerializable对象时,抛出StackOverflowException。

浏览:30日期:2024-02-17
如何解决使用ReferenceLoopHandling.Ignore序列化依赖于循环的ISerializable对象时,抛出StackOverflowException。?

我想你会需要同时ReferenceLoopHandling.Serialize和PreserveReferencesHandling.All复制二进制序列化的行为。但是,生成的JSON可能不那么漂亮。

我对JSON.Net4.5r10进行了更深入的研究,发现了一个缺陷:JsonSerializerInternalWriter不检查#ShouldWriteReference通过获得的引用ISerializable。

随着foreach循环中#SerializeISerializable,如下改写,你的对象图顺利往返。

foreach (SerializationEntry serializationEntry in serializationInfo) { writer.WritePropertyName(serializationEntry.Name); var entryValue = serializationEntry.Value; var valueContract = GetContractSafe(entryValue); if (ShouldWriteReference(entryValue, null, valueContract, null, member)) { WriteReference(writer, entryValue); } else { SerializeValue(writer, entryValue, valueContract, null, null, member); } }解决方法

我有一个使用二进制序列化来保留数据的旧版应用程序。现在,我们想使用Json.net 4.5在不对现有类进行太多更改的情况下序列化数据。

事情一直很好,直到我们遇到了循环依赖类。有解决此问题的解决方法吗?

示例代码如下所示

[Serializable]class Department : ISerializable{ public Employee Manager { get; set; } public string Name { get; set; } public Department() { } public Department( SerializationInfo info,StreamingContext context ) {Manager = ( Employee )info.GetValue( 'Manager',typeof( Employee ) );Name = ( string )info.GetValue( 'Name',typeof( string ) ); } public void GetObjectData( SerializationInfo info,StreamingContext context ) {info.AddValue( 'Manager',Manager );info.AddValue( 'Name',Name ); }}[Serializable]class Employee : ISerializable{ [NonSerialized] //This does not work [XmlIgnore]//This does not work private Department mDepartment; public Department Department {get { return mDepartment; }set { mDepartment = value; } } public string Name { get; set; } public Employee() { } public Employee( SerializationInfo info,StreamingContext context ) {Department = ( Department )info.GetValue( 'Department',typeof( Department ) );Name = ( string )info.GetValue( 'Name',typeof( string ) ); } public void GetObjectData( SerializationInfo info,StreamingContext context ) {info.AddValue( 'Department',Department );info.AddValue( 'Name',Name ); }}

和测试代码

Department department = new Department();department.Name = 'Dept1';Employee emp1 = new Employee { Name = 'Emp1',Department = department };department.Manager = emp1;Employee emp2 = new Employee() { Name = 'Emp2',Department = department };IList<Employee> employees = new List<Employee>();employees.Add( emp1 );employees.Add( emp2 );var memoryStream = new MemoryStream();var formatter = new BinaryFormatter();formatter.Serialize( memoryStream,employees );memoryStream.Seek( 0,SeekOrigin.Begin );IList<Employee> deserialisedEmployees = formatter.Deserialize( memoryStream ) as IList<Employee>; //Works nicelyJsonSerializerSettings jsonSS= new JsonSerializerSettings();jsonSS.TypeNameHandling = TypeNameHandling.Objects;jsonSS.TypeNameAssemblyFormat = FormatterAssemblyStyle.Full;jsonSS.Formatting = Formatting.Indented;jsonSS.ReferenceLoopHandling = ReferenceLoopHandling.Ignore; //This is not working!!//jsonSS.ReferenceLoopHandling = ReferenceLoopHandling.Serialize; //This is also not working!!jsonSS.PreserveReferencesHandling = PreserveReferencesHandling.All;string jsonAll = JsonConvert.SerializeObject( employees,jsonSS ); //Throws stackoverflow exception

Edit1:该问题已报告给Json(http://json.codeplex.com/workitem/23668)

Edit2 :序列化在版本4.5 R11中可以正常工作,但是反序列化仍然不起作用

Edit3 :当循环引用对象不为null时,实际上序列化本身不起作用

Edit4 :来自Json.net问题库的评论是问题在您的末端,并已解决问题。但是我找不到我的代码出了什么问题。我对此发布了另一个

相关文章: