2013-04-20 48 views
2

這會在運行時導致序列化異常。這只是一個演示項目來測試這樣做的最佳方式。我包括了主要的方法和即將嘗試序列化的類。我在序列化時犯了什麼錯誤?

忽略:我真的無法添加更多的細節,我已經描述了這個問題,附上代碼,這個「請添加更多細節」的東西是有史以來最愚蠢的事情。我已經發布了。

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.Data' 'SerializationDemo, 版本= 1.0.0.0,文化=中性公鑰=空' 未標記 爲可序列化。

+1

@walther在程序集'SerializationDemo,Version = 1.0.0.0,Culture = neutral,PublicKeyToken = null'中鍵入'SerializationDemo.Data'未被標記爲可序列化。 – Innkeeper 2013-04-20 14:17:26

+0

等等......這是否意味着我還需要[]屬性?不是從界面派生出來的嗎? – Innkeeper 2013-04-20 14:18:32

+1

'[Serializable]'是你需要的 – IAbstract 2013-04-20 14:18:58

回答

4

答案是給你在異常消息:

類型 'SerializationDemo.Data' 在大會 'SerializationDemo, 版本= 1.0.0.0,文化=中立,公鑰=空' 是未標記爲 可序列化。

您需要使用Serializable屬性標記您的班級。

[Serializable()] 
class Data : ISerializable 

從它好像你將要傳遞下來的網絡對象的情況下(推斷是由於局部變量名toSend要獲取)。您需要注意的是,如果您使用客戶端 - 服務器模式,則序列化並從服務器軟件發送的對象默認情況下不會從客戶端軟件反序列化。

這是因爲二進制序列化的基本特徵是它保留了類型系統保真度。類型系統保真度表示類型信息在序列化過程中不會丟失。這意味着當你序列化一個對象時,不僅是寫入數據流的「對象的狀態」,而且是類和包含程序集的名稱。即使您在要反序列化數據的程序集中定義類Data,反序列化方法也會失敗(拋出異常),因爲解串器將尋找類型Program1.Namespace.Data而不是Program2.Namespace.Data。爲了彌補這一點,您可以在相互彙編(類庫)中定義數據消息,或者定義一個SerializationBinder,這將允許您基本上使用反序列化方法來認爲您仍然在同一個程序集中。

+0

這比我想象的要複雜得多,這只是一個虛擬測試程序,但是,我的意圖是通過tcp連接發送它。因此,在DLL中定義類並將其鏈接到服務器和客戶端項目中是一個好策略?上下文是一個多人國際象棋應用程序,我想傳輸電路板實例。 – Innkeeper 2013-04-21 21:57:43

+0

@Innkeeper我認爲在自己的程序集中定義你的消息是一個好主意,因爲它使得序列化過程更容易,也意味着你不必複製和粘貼類,並且可能每次都在程序集中枚舉消息標識符你添加一條新消息。唯一的缺點是,你的應用程序將依賴於你的DLL,並且不再是獨立的可執行文件。 – 2013-04-22 06:17:54

相關問題