2
votes

My winforms application has a custom control, one of its property "LayoutStream" is byte[] type and it is serializable property. Currently I have ported my application from 4.6 framework to NetCore 3.0 project.

While run ported NetCore 3.0 project, im getting below exception when deserialize the data from resx file.

this.control1.LayoutStream = ((SerializableByteList)(resources.GetObject("control1.LayoutStream")));


    public SerializableByteList LayoutStream
    {
        get
        {
            return LayoutStream;
        }
        set
        {
            LayoutStream= value;
            if (value != null)
                this.stmLayout.Write(value.Bytes.ToArray(), 0, value.Bytes.ToArray().Length);
        }
    }

    [Serializable]
    public class SerializableByteList 
    {
        public SerializableByteList()
        {
            Bytes = new List<byte>();
        }
        public List<byte> Bytes { get; set; }
    }

Exception Occurs: Exception thrown: 'System.Runtime.Serialization.SerializationException' in System.Runtime.Serialization.Formatters.dll An unhandled exception of type 'System.Runtime.Serialization.SerializationException' occurred in System.Runtime.Serialization.Formatters.dll Unable to find assembly 'mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'

Please suggest solution to resolve this.

1

1 Answers

2
votes

Fundamentally, BinaryFormatter is not portable; it was designed for remoting between two nodes running identical code, not persisting data between frameworks. So: my main advice is simply:

Don't use BinaryFormatter. Ever.

I realise this boat may have sailed, but a very pragmatic option is to:

  • pick a new serializer - making sure it is portable (json, xml, protobuf, etc); just about anything except BinaryFormatter
  • in your old code, deserialize the data with your current code, and serialize it separately with the new choice of serializer
  • in your new code, deserialize it in the new format only

At a push, however, you could try playing with a custom SerializationBinder; the idea here is that you subclass SerializationBinder, override the methods, and tell it where to find things. The fundamental problem here is that:

  1. the assemblies (mscorlib etc) have changed identity
  2. types have moved between assemblies in many cases

Both of those problems need handling.

Partial code:

var bf = new BinaryFormatter { Binder = MyBinder.Instance };
// etc

with

class MyBinder : SerializationBinder
{
    private MyBinder() { }
    public static MyBinder Instance { get; } = new MyBinder();
    public override Type BindToType(string assemblyName, string typeName)
    {
        // TODO: check assemblyName and typeName against some known list, and
        // return the Type that should be used, often *instead of* the
        // one it expected;
    }
    public override void BindToName(Type serializedType,
        out string assemblyName, out string typeName)
    {
        //TODO: the opposite
    }
}

But this is hard work, and absurdly brittle. Your time would be much better spent porting to a different serializer, IMO. Happy to recommend some, depending on your needs.


Side note: they have tried repeatedly to kill BinaryFormatter for .NET Core, but it sadly survived.