3

This leads to serialization exception at runtime. It's just a demo project to test the best way to do this. I included the main method and the class which im trying to serialize.

Ignore: I really cant add more detail, i've described the problem, attached the code, this "please add more details" thing is the stupidest thing ever. Let me post it already.

Data toSend = new Data();
toSend.Output();

///SERIALIZE

BinaryFormatter formatter = new BinaryFormatter();
Stream streamOut = File.OpenWrite("file");
formatter.Serialize(streamOut, toSend);
streamOut.Close();


Console.WriteLine("----------------------------");
///DESERIALIZE

Stream streamIn = File.OpenRead("file");
Object received = formatter.Deserialize(streamIn);
Data toReceive = (Data)received;
toReceive.Output();

class Data : ISerializable
{
    int integerData;
    string stringData;
    bool booleanData;
    int shouldnotbeserialized;

    public Data()
    {
        integerData = 1;
        stringData = "Hello";
        booleanData = true;
        shouldnotbeserialized = 55;
    }

    //To deserialize
    public Data(SerializationInfo info, StreamingContext context)
    {
        integerData = info.GetInt32("theint");
        stringData = info.GetString("thestring");
        booleanData = info.GetBoolean("thebool");
    }

    public void Output()
    {
        Console.WriteLine(integerData);
        Console.WriteLine(stringData);
        Console.WriteLine(booleanData);
        Console.WriteLine(shouldnotbeserialized);
    }

    //Implemented method to serialize
    public void GetObjectData(SerializationInfo info, StreamingContext context)
    {
        info.AddValue("thestring", stringData);
        info.AddValue("theint", integerData);
        info.AddValue("thebool", booleanData);
    }
}

Exception message:

Type 'SerializationDemo.Data' in Assembly 'SerializationDemo, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' is not marked as serializable.

walther
  • 13,466
  • 5
  • 41
  • 67
Innkeeper
  • 663
  • 1
  • 10
  • 22
  • 1
    @walther Type 'SerializationDemo.Data' in Assembly 'SerializationDemo, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' is not marked as serializable. – Innkeeper Apr 20 '13 at 14:17
  • Wait... Does that mean, I need the [] attribute also? Isn't deriving from the interface enough? – Innkeeper Apr 20 '13 at 14:18
  • 1
    `[Serializable]` is what you need – IAbstract Apr 20 '13 at 14:18
  • Okay, that was the problem... But I still don't understand what the attribute does when it marks a class as serializable. – Innkeeper Apr 20 '13 at 14:20
  • I'm sure there is a duplicate question where the missing attribute is the problem. – IAbstract Apr 20 '13 at 14:20
  • @IAbstract Okay, I'll check out what these attributes are about. Thanks! – Innkeeper Apr 20 '13 at 14:21
  • @Innkeeper maybe you should edit your question to be 'Why do I need the [Serializable] attribute if I derive from ISerializable?' – John MacIntyre Apr 20 '13 at 14:23
  • @JohnMacIntyre I think the reason i dont know that is because i dont really know anything about attributes. – Innkeeper Apr 20 '13 at 14:24
  • These links might help you. http://www.codeproject.com/Articles/390422/Quick-Overview-of-Csharp-Attribute-Programming and http://stackoverflow.com/a/8594980/29043 – John MacIntyre Apr 20 '13 at 14:30
  • possible duplicate of [What's the difference between using the Serializable attribute & implementing ISerializable?](http://stackoverflow.com/questions/2365152/whats-the-difference-between-using-the-serializable-attribute-implementing-is) – Matthew Strawbridge Apr 20 '13 at 14:34
  • @Innkeeper, I do not see where you call `GetObjectData`. If you put a breakpoint on your code, is it called? ...ever? –  Mar 20 '17 at 15:11

1 Answers1

9

The answer is given to you in the exception message:

Type 'SerializationDemo.Data' in Assembly 'SerializationDemo, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' is not marked as serializable.

You need to mark your class with the Serializable attribute.

[Serializable()]
class Data : ISerializable

From the context it seems like you are going to be transmitting the object down a network (deduced due to the local variable names toSend, toReceive). You need to be aware that, if you where for example, using a client-server model, an object serialized and sent from the server software will not be deserializable from the client software by default.

This is because the fundamental characteristic of binary serialization is that it preserves type system fidelity. Type system fidelity denotes that type information is not lost in the serialization process. This means that when you serialize an object, is is not only the "object's state" written to the data stream, but also the name of the class and the containing assembly. Even if you defined the class Data in the assembly that is going to deserialize the data, the deserialize method will fail (throw an exception) because the deserializer will be looking for the type Program1.Namespace.Data not Program2.Namespace.Data. To remedy this you can define your data messages in a mutual assembly (class library) or by defining a SerializationBinder that will allow you to basically trick the deserialize method into thinking you are still in the same assembly.

User 12345678
  • 7,714
  • 2
  • 28
  • 46
  • 1
    It's more complex than I thought then, this is just a dummy test program, but yes, my intention was to send it through a tcp connection. So is it a good strategy to define the class in a DLL, and link it in both server and client projects? The context is a multiplayer chess app, and I want to transmit the board instance. – Innkeeper Apr 21 '13 at 21:57
  • @Innkeeper I think defining your messages in their own assembly is a good idea because it makes the serialization process easier and it also means you don't have to copy and paste the class, and possibly an enumeration of message identifiers across assemblies every time you add a new message. The only down side is, is that your application will be dependent on your DLL and will not be stand-alone executable anymore. – User 12345678 Apr 22 '13 at 06:17