我在序列化时犯了什么错误?

本文关键字:什么 错误 序列化 | 更新日期: 2023-09-27 18:10:12

这会在运行时导致序列化异常。这只是一个演示项目,用于测试实现此功能的最佳方法。我包含了main方法和我试图序列化的类。

忽略:我真的不能添加更多的细节,我已经描述了问题,附上了代码,这种"请添加更多细节"的事情是有史以来最愚蠢的事情。我已经把它贴出来了。

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);
    }
}

异常信息:

SerializationDemo类型"。数据"汇编中"序列化版本=1.0.0.0,文化=中性,PublicKeyToken=null'未被标记是可序列化的。

我在序列化时犯了什么错误?

在异常消息中给出了答案:

SerializationDemo类型"。数据"汇编中"序列化版本=1.0.0.0,文化=中性,PublicKeyToken=null'未标记是可序列化的。

你需要用Serializable属性标记你的类。

[Serializable()]
class Data : ISerializable

从上下文中来看,似乎您将通过网络传输对象(由于局部变量名称toSendtoReceive推断)。您需要意识到,例如,如果您使用客户端-服务器模型,那么从服务器软件序列化并发送的对象在默认情况下将无法从客户端软件反序列化。

这是因为二进制序列化的基本特征是它保持了类型系统的保真度。类型系统保真度表示类型信息不会在序列化过程中丢失。这意味着,当您序列化一个对象时,不仅会将"对象的状态"写入数据流,还会将类和包含该对象的程序集的名称写入数据流。即使您在程序集中定义了将对数据进行反序列化的类Data,反序列化方法也会失败(抛出异常),因为反序列化器将查找类型Program1.Namespace.Data而不是Program2.Namespace.Data。为了解决这个问题,您可以在相互的程序集(类库)中定义数据消息,或者通过定义SerializationBinder来欺骗反序列化方法,使其认为您仍然在同一个程序集中。