Search code examples
c#serializationbinary-serialization

C# - Binary Serialization InvalidCastException


So I have a class called OutputInformation which I'd like to store and then read on another computer to retrieve the data.

I'm using binary serialization.

[Serializable()]
public class OutputInformation
{
    public List<string> filenames { get; set; }
    public long[] filesizes { get; set; }
}

public void Write()
{
    OutputInformation V = new OutputInformation();
    V.filesizes = sizearray;
    V.filenames = namelist;
    IFormatter formatter = new BinaryFormatter();
    Stream stream = new FileStream("D:\\MyFile.bin", FileMode.Create, 
                         FileAccess.Write, FileShare.None);
    formatter.Serialize(stream, V);
    stream.Close();
}

The serialization is done within a user control and if I deserialize in the user control, it works fine.

But if I try to deserialize from my main window, I get an invalidcastexception. So I would imagine the same problem would occur if I tried to deserialize the file from another computer.

How do I solve this? I just need to store the class in a file and retrieve it later from a different computer. Preferably not use XML serialization.

[Serializable()]
public class OutputInformation
{
    public List<string> filenames { get; set; }
    public long[] filesizes { get; set; }
}

IFormatter formatter = new BinaryFormatter();
Stream stream = new FileStream("D:\\MyFile.bin", FileMode.Open, 
                                          FileAccess.Read, FileShare.Read);
OutputInformation obj = (OutputInformation)formatter.Deserialize(stream);
stream.Close();

Error is an InvalidCastException. Additional information: [A]OutputInformation cannot be cast to [B]OutputInformation.


Solution

  • Both classes should be in the same namespace. Define your OutputInformation class on deserialization in exact the same namespace as on serialization (or refer assembly with it).

    Or, if it is not possible, or you prefer not to do it, you should write your own implementation of SerializationBinder

    public class ClassOneToNumberOneBinder : SerializationBinder
    {
        public override Type BindToType(string assemblyName, string typeName)
        {
            typeName = typeName.Replace(
                "oldNamespace.OutputInformation",
                "newNamespace.OutputInformation");
    
            return Type.GetType(typeName);
        }
    }
    

    And set it before deserialization:

    formatter.Binder = new ClassOneToNumberOneBinder();
    

    Look here for more details: Is it possible to recover an object serialized via "BinaryFormatter" after changing class names?