Serialiazing/Deserializing list of custom class: Could not find type

Hello,

I’m trying to send serialized data over a NetworkStream. The data is made of a Payload class, with a few fields, including one field that inherits from a custom PayloadType Class. WorldDescription is a simple class with two string fields.

I initially had this work just fine on .NET, but within Unity, I get a:
******* Could not find type ‘System.Collections.Generic.List`1[[ResServerLib.Data.WorldDescription, ResServerLib, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]’.**

EDIT

So I did further attemps

  • I tried to change to a List instead of the List , it works

  • I added a WorldDescription field directly to the payload (not in a List), it works

→ So it seems the issue is really about the List of WorldDescription, which at the moment is nothing more than:

[Serializable]
    public class WorldDescription
    {
        public string worldName;
        public bool isAvailable;

        public WorldDescription(string worldName, bool isAvailable)
        {
            this.worldName = worldName;
            this.isAvailable = isAvailable;
        }
    }

I serialize with

         private byte[] PayloadToByteArray(Payload obj)
        {
            if (obj == null)
                return null;
            BinaryFormatter binForm = new BinaryFormatter();
            binForm.Binder = new VersionDeserializationBinder();

            MemoryStream ms = new MemoryStream();
            binForm.Serialize(ms, obj);
            return ms.ToArray();
        }

And I deserialize with:

        private static Payload ByteArrayToPayload(byte[] arrBytes)
        {
            try
            {
                MemoryStream memStream = new MemoryStream();
                BinaryFormatter binForm = new BinaryFormatter();
                binForm.Binder = new VersionDeserializationBinder();

                memStream.Write(arrBytes, 0, arrBytes.Length);
                memStream.Seek(0, SeekOrigin.Begin);

                Payload obj = (Payload)binForm.Deserialize(memStream);

                return obj;
            }
            catch (Exception ex)
            {
                Debug.WriteLine(" *****     " + ex.Message);
                return null;
            }
        }

Originally, I didn’t use the SerializationBinder, but read that Unity had issues indicating the correct type. This effectively worked when Serializing in Unity and Deserializing in the serverapplication (edit: actually, in that case, I was only sending a PayloadType without a List<> field), but Unity still can’t Deserialize server data, throwing the error above.

The SerializationBinder is (taken from here)

 public sealed class VersionDeserializationBinder : SerializationBinder
        {
            public override Type BindToType(string assemblyName, string typeName)
            {
                if (!string.IsNullOrEmpty(assemblyName) && !string.IsNullOrEmpty(typeName))
                {
                    Type typeToDeserialize = null;
                     assemblyName = Assembly.GetExecutingAssembly().FullName;

                    // The following line of code returns the type. 
                    //typeToDeserialize = Type.GetType(String.Format("{0}, {1}", typeName, assemblyName));
                    typeToDeserialize = GetType(typeName);
   
                    return typeToDeserialize;
                }

                return null;
            }

Any thoughts or suggestions?

Thanks in advance!

Alright, so after trying this in every way possible, I still had an issue deserializing the list<> in Unity (or serializing it for that matter). It worked on my .net app that I use as a server.

I looked into other means of serialization, and I found Protobuf-net, which incidentally has a Unity-specific release. It’s pretty simple to set up, and the serialization/deserialization code is simpler and faster than BinaryFormatter. More importantly, it works!!

        private byte[] PayloadToByteArray(Payload obj)
        {
            if (obj == null)
                return null;

            using (MemoryStream ms = new MemoryStream())
            {
                Serializer.Serialize(ms, this);
                return ms.ToArray();
            }
        }

        private static Payload ByteArrayToPayload(byte[] arrBytes)
        {
              using (MemoryStream memStream = new MemoryStream())
            {
                memStream.Write(arrBytes, 0, arrBytes.Length);
                memStream.Seek(0, SeekOrigin.Begin);
                return Serializer.Deserialize<Payload>(memStream);
            }
        }