-
-
Save bahusoid/ecdd9119c30fef5e08585761a015b96b to your computer and use it in GitHub Desktop.
Workaround for deserialization exception (broken)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.IO; | |
using System.Runtime.Serialization; | |
using System.Runtime.Serialization.Formatters.Binary; | |
namespace ConsoleApp12 | |
{ | |
public static class Program | |
{ | |
public static void Main() | |
{ | |
var myClass = new MyProxy | |
{ | |
Id = 1, | |
Ref = new MyProxy | |
{ | |
Id = 2, | |
Ref = new MyProxy() | |
{ | |
Id = 3, | |
} | |
} | |
}; | |
var result1 = SpoofSerialization(myClass); | |
Console.WriteLine("Ok without circular references"); | |
// Add circular reference | |
myClass.Ref.Ref = myClass; | |
var result2 = SpoofSerialization(myClass); | |
Console.WriteLine(result2.Ref.Ref == result2 ? "Works too!": "Fails to restore circular reference!" ); | |
} | |
[Serializable] | |
public class MyProxy : ISerializable | |
{ | |
private MyProxyObjWrapper _proxyRef; | |
public int Id { get; set; } | |
public MyProxy Ref { get; set; } | |
public MyProxy() | |
{ | |
_proxyRef = new MyProxyObjWrapper(this); | |
} | |
public void GetObjectData(SerializationInfo info, StreamingContext context) | |
{ | |
info.SetType(typeof(MyProxyObjRef)); | |
// Use IObjectReference only inside proxy | |
new MyProxyObjRef(this).GetObjectData(info, context); | |
} | |
[Serializable] | |
class MyProxyObjRef : MyProxyObjWrapper, IObjectReference | |
{ | |
public MyProxyObjRef(MyProxy myProxy) : base(myProxy) | |
{ | |
} | |
private protected MyProxyObjRef(SerializationInfo info, StreamingContext context) : base(info, context) | |
{ | |
} | |
} | |
[Serializable] | |
class MyProxyObjWrapper : ISerializable | |
{ | |
private MyProxy _myProxy; | |
public MyProxyObjWrapper(MyProxy myProxy) | |
{ | |
_myProxy = myProxy; | |
} | |
private protected MyProxyObjWrapper(SerializationInfo info, StreamingContext context) | |
{ | |
_myProxy = new MyProxy | |
{ | |
Id = info.GetInt32(nameof(MyProxy.Id)), | |
Ref = ((MyProxyObjWrapper) info.GetValue(nameof(MyProxy.Ref), typeof(MyProxyObjWrapper)))?._myProxy, | |
}; | |
} | |
public void GetObjectData(SerializationInfo info, StreamingContext context) | |
{ | |
info.AddValue(nameof(_myProxy.Id), _myProxy.Id); | |
// Use wrapper | |
info.AddValue(nameof(_myProxy.Ref), _myProxy.Ref?._proxyRef, typeof(MyProxyObjWrapper)); | |
} | |
public object GetRealObject(StreamingContext context) | |
{ | |
return _myProxy; | |
} | |
} | |
} | |
private static T SpoofSerialization<T>(T session) | |
{ | |
var formatter = new BinaryFormatter(); | |
var stream = new MemoryStream(); | |
formatter.Serialize(stream, session); | |
stream.Position = 0; | |
return (T) new BinaryFormatter().Deserialize(stream); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment