[Mono-list] problems with SerializationBinder

Ishpal Singh ishpal.singh@aeye.net
Tue, 18 Feb 2003 22:39:57 -0000


Hi guys,

A brief report reagrding the BinaryFormatter/Serialization which can be
helpful to you guys.
Thought I'd mail the bug (if I am not doing anything wrong :)). It might
help a few.

I am trying to work with the deserialization with mono.
Passing a structure from a windows application running dotNet to the linux
box running mono and try to recover the same object on the linux machine.
It seems to transfer the data fine, but then it checks for the header of the
serialized structure and finds the assembly name in which the structure was
originally serialized.
Now, since the two applications are different, the assembly names are also
obviously different and so while deserializing it complains for the assembly
names. (refer http://msdn.microsoft.com/msdnmag/issues/02/09/net/ )
To work around I wrote another class called the
'AssmNameChangeDeserializationBinder'. The purpose of this binder is to
replace the assembly name when it reaches the other application.
It works fine if both the applications are on windows, but fails if one of
the application is on MONO. MONO doesnt seem to invoke this class to change
the assembly name while deserializing.
I think this needs to be fixed.

-----------------------------------------------
using System;
namespace cmsStruct
{
	[Serializable()]
	public struct test
	{
		public int a;
		public string b;
	}
}
-----------------------------------------------

MemoryStream ms = new MemoryStream(b);
BinaryFormatter bf1 = new BinaryFormatter();
ms.Position = 0;
bf1.Binder = new AssmNameChangeDeserializationBinder();

cmsStruct.test t = (cmsStruct.test) bf1.Deserialize(ms);

--------------------------------------------------------------------

sealed class AssmNameChangeDeserializationBinder :
System.Runtime.Serialization.SerializationBinder
		{
			public override Type BindToType( string assemblyName, string typeName)
			{

				Console.WriteLine("in Bind to type...");

				Type typeToDeserialize = null;

				// For each assemblyName/typeName that you wish to deserialize
				// to a different type, set typeToCreate to the desired type
				String assemVer1 = "TransferStructData, Version=1.0.0.0, " +
					"Culture=neutral, PublicKeyToken=b77a5c561934e089";
				String typeVer1 = "cmsStruct.test";

				Console.WriteLine("assemblyName={0}", assemblyName);

				if (assemblyName.IndexOf( "TransferStructData") != -1)// && typeName ==
typeVer1)
				{
					assemblyName = assemblyName.Replace("TransferStructData",
"dotNetServer");
				}

				// To return the type, do this:
				typeToDeserialize = Type.GetType(String.Format("{0}, {1}",
					typeName, assemblyName));

				return typeToDeserialize;
			}
		}


------------------------------------------------------------------

WORAROUND TO GET IT GOING ON MONO
---------------------------------
I had to change the name of the assembly while serializing the structure,
after inheriting it from ISerializable as the following code shows.
The code with following structure to transfer data works on both windows and
mono.
And no need to use the Binder to chahge the name of the Assembly at the time
of deserialization.

using System;
using System.IO;
using System.Runtime.Serialization;

namespace cmsStruct
{
	[Serializable()]
	public struct test : ISerializable
	{
		public int a;
		public string b;

		//Deserialization constructor.
		public test (SerializationInfo info, StreamingContext context)
		{
			a = (int)info.GetValue("a", typeof(int));
			b = (String)info.GetValue("b", typeof(string));
		}


		public void GetObjectData(SerializationInfo info, StreamingContext
context)
		{
			info.AddValue("a", a);
			info.AddValue("b", b);
			info.AssemblyName = "dotNetServer";
		}
	}
}
-------------------------------------


Please let me know incase someone needs some more information or if I am
creating confusions.


Best Regards,
Ishpal Singh.

System Analyst
R&D
Aeye Ltd

Information contained in this email is confidential and is intended only
for the recipient. (c) Aeye Ltd, Aeye.biz, 2003.