+
+ [Test]
+ public void GenericArray ()
+ {
+ Comparable [] a = new Comparable [1];
+ a [0] = new Comparable ();
+
+ BinaryFormatter bf = new BinaryFormatter ();
+ MemoryStream ms = new MemoryStream ();
+
+ bf.Serialize (ms, a);
+
+ ms.Position = 0;
+ Comparable [] b = (Comparable []) bf.Deserialize (ms);
+
+ Assert.AreEqual (a.Length, b.Length, "#1");
+ Assert.AreEqual (a [0], b [0], "#2");
+ }
+
+ public Stream GetSerializedStream ()
+ {
+ SerializationTest test = new SerializationTest (true, Int32.MinValue);
+ BinaryFormatter bf = new BinaryFormatter ();
+ MemoryStream ms = new MemoryStream ();
+ bf.Serialize (ms, test);
+ ms.Position = 0;
+ return ms;
+ }
+
+ [Test]
+ public void QualifiedField()
+ {
+ QualifiedFieldTest a = new QualifiedFieldTest ();
+ a.ValueA = 1;
+ a.ValueB = 2;
+ a.Value = 3;
+ Stream ms = new MemoryStream ();
+ BinaryFormatter bf = new BinaryFormatter ();
+ bf.Serialize(ms, a);
+ ms.Position = 0;
+ QualifiedFieldTest b = (QualifiedFieldTest)bf.Deserialize (ms);
+ Assert.AreEqual (a.ValueA, b.ValueA, "#1");
+ Assert.AreEqual (a.ValueB, b.ValueB, "#2");
+ Assert.AreEqual (a.Value, b.Value, "#3");
+ }
+
+#if NET_4_0
+ [Test]
+ public void SerializationBindToName ()
+ {
+ BinaryFormatter bf = new BinaryFormatter ();
+ bf.AssemblyFormat = FormatterAssemblyStyle.Full;
+ bf.Binder = new SimpleSerializationBinder ();
+ MemoryStream ms = new MemoryStream ();
+
+ SimpleSerializableObject o = new SimpleSerializableObject ();
+ o.Name = "MonoObject";
+ o.Id = 666;
+
+ bf.Serialize (ms, o);
+ ms.Position = 0;
+
+ o = (SimpleSerializableObject)bf.Deserialize (ms);
+ Assert.AreEqual ("MonoObject", o.Name);
+ Assert.AreEqual (666, o.Id);
+ }
+
+ class SimpleSerializationBinder : SerializationBinder
+ {
+ public override Type BindToType (string assemblyName, string typeName)
+ {
+ // We *should* be getting a SimpleSerializableObject2 instance
+ // Otherwise it means we are not getting called our BindToName method.
+ if (!typeName.EndsWith ("SimpleSerializableObject2"))
+ Assert.Fail ("#BindToType-TypeName");
+
+ // We are also supposed to be getting a 9.9.9.9 version here,
+ // and if we get a different version, it likely means BindToName was called.
+ AssemblyName aname = Assembly.GetExecutingAssembly ().GetName ();
+ aname.Version = new Version (9, 9, 9, 9);
+ if (aname.ToString () != assemblyName)
+ Assert.Fail ("#BindToType-AssemblyName");
+
+ // No need to call Type.GetType
+ return typeof (SimpleSerializableObject);
+ }
+
+ public override void BindToName (Type serializedType, out string assemblyName, out string typeName)
+ {
+ AssemblyName aname = Assembly.GetExecutingAssembly ().GetName ();
+ aname.Version = new Version (9, 9, 9, 9);
+
+ // Serialize mapping to this same assembly with 9.9.9.9 version
+ // and a different type name.
+ assemblyName = aname.ToString ();
+ typeName = serializedType.FullName.Replace ("SimpleSerializableObject", "SimpleSerializableObject2");
+ }
+ }
+
+ [Serializable]
+ class SimpleSerializableObject
+ {
+ public string Name { get; set; }
+ public int Id { get; set; }
+ }
+
+ [Test]
+ public void SerializationBindToName2 ()
+ {
+ BinaryFormatter bf = new BinaryFormatter ();
+ bf.AssemblyFormat = FormatterAssemblyStyle.Full;
+ bf.Binder = new SimpleSerializationBinder2 ();
+ MemoryStream ms = new MemoryStream ();
+
+ SimpleISerializableObject o = new SimpleISerializableObject ();
+ o.Name = "MonoObject";
+ o.Id = 666;
+
+ bf.Serialize (ms, o);
+ ms.Position = 0;
+
+ o = (SimpleISerializableObject)bf.Deserialize (ms);
+ Assert.AreEqual ("MonoObject", o.Name);
+ Assert.AreEqual (666, o.Id);
+
+ ms.Close ();
+ }
+
+ [Test]
+ public void NestedObjectReferences ()
+ {
+ MemoryStream ms = new MemoryStream ();
+
+ var cls = new Class { Name = "MyClass" };
+ var ob = cls.NewInstance ();
+
+ BinaryFormatter bf = new BinaryFormatter();
+ bf.Serialize (ms, new DynamicProxy (ob));
+
+ ms.Position = 0;
+
+ Instance ins = (Instance) bf.Deserialize (ms);
+ Assert.AreEqual ("MyClass", ins.Class.Name);
+ }
+
+ class SimpleSerializationBinder2 : SerializationBinder
+ {
+ public override void BindToName (Type serializedType, out string assemblyName, out string typeName)
+ {
+ AssemblyName aname = Assembly.GetExecutingAssembly ().GetName ();
+ aname.Version = new Version (9, 9, 9, 9);
+
+ // Serialize mapping to this same assembly with 9.9.9.9 version
+ // and a different type name.
+ assemblyName = aname.ToString ();
+ typeName = serializedType.FullName.Replace ("SimpleISerializableObject", "SimpleISerializableObject2");
+ }
+
+ public override Type BindToType (string assemblyName, string typeName)
+ {
+ // We *should* be getting a SimpleISerializableObject2 instance
+ if (!typeName.EndsWith ("SimpleISerializableObject2"))
+ Assert.Fail ("#BindToType-TypeName");
+
+ // We are also supposed to be getting a 9.9.9.9 version here,
+ // and if we get a different version, it likely means BindToName was called.
+ AssemblyName aname = Assembly.GetExecutingAssembly ().GetName ();
+ aname.Version = new Version (9, 9, 9, 9);
+ if (aname.ToString () != assemblyName)
+ Assert.Fail ("#BindToType-AssemblyName");
+
+ return typeof (SimpleISerializableObject);
+ }
+ }
+
+ [Serializable]
+ class SimpleISerializableObject : ISerializable
+ {
+ public string Name { get; set; }
+ public int Id { get; set; }
+
+ public SimpleISerializableObject ()
+ {
+ }
+
+ protected SimpleISerializableObject (SerializationInfo info, StreamingContext context)
+ {
+ Name = info.GetString ("Name");
+ Id = info.GetInt32 ("Id");
+ }
+
+ public void GetObjectData (SerializationInfo info, StreamingContext context)
+ {
+ info.AddValue ("Name", Name);
+ info.AddValue ("Id", Id);
+ }
+ }
+
+ [Serializable]
+ public class OtherClass
+ {
+ }
+
+ [Serializable]
+ public class BaseClass
+ {
+ public OtherClass Other { get; set; }
+ }
+
+ public class CustomSerBinder: SerializationBinder
+ {
+ public override void BindToName (Type serializedType, out string assemblyName, out string typeName)
+ {
+ assemblyName = null;
+ if (serializedType == typeof (BaseClass))
+ typeName = "base";
+ else if (serializedType == typeof (OtherClass))
+ typeName = "other";
+ else
+ throw new ArgumentException ("Unknown type", "serializedType");
+ }
+
+ public override Type BindToType (string assemblyName, string typeName)
+ {
+ switch (typeName) {
+ case "base":
+ return typeof (BaseClass);
+ case "other":
+ return typeof (OtherClass);
+ default:
+ throw new ArgumentException ("Unknown type name", "typeName");
+ }
+ }
+ }
+
+ [Test]
+ public void BinderShouldBeUsedForProperties ()
+ {
+ using (var serStream = new MemoryStream ()) {
+ var binder = new CustomSerBinder ();
+
+ // serialize
+ var original = new BaseClass () {
+ Other = new OtherClass ()
+ };
+ var formatter = new BinaryFormatter ();
+ formatter.Binder = binder;
+ formatter.Serialize (serStream, original);
+
+ // deserialize, making sure we're using a new formatter, just to be thorough
+ formatter = new BinaryFormatter ();
+ formatter.Binder = binder;
+ serStream.Seek (0, SeekOrigin.Begin);
+ var deserialized = formatter.Deserialize (serStream);
+
+ Assert.AreEqual (original.GetType (), deserialized.GetType ());
+ Assert.AreEqual (original.Other.GetType (), ((BaseClass)deserialized).Other.GetType ());
+ }
+ }
+#endif