C#自定義序列化_第1頁
C#自定義序列化_第2頁
C#自定義序列化_第3頁
全文預覽已結(jié)束

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)

文檔簡介

自定義序列化自定義序列化是控制某種類型的序列化和反序列化的過程。通過控制序列化,可以確保序列化的兼容性,即可以在某個類型的不同版本之間序列化和反序列化,而不會破壞該類型的核心功能。例如,在某個類型的第一個版本中,可能只有兩個字段。在某個類型的下一版本中,又增加了幾個字段。然而,應用程序的第二版必須能夠?qū)@兩種類型進行序列化和反序列化。以下各節(jié)描述如何控制序列化。在序列化期間和之后運行自定義方法最佳做法也是最簡單的方法(在.NetFramework2.0版中引入),就是在序列化期間和之后將下列屬性應用于用于更正數(shù)據(jù)的方法:OnDeserializedAttributeOnDeserializingAttributeOnSerializedAttributeOnSerializingAttribute這些屬性使該類型可以參與序列化和反序列化過程的任何一個階段或全部四個階段。屬性指定在每個階段應調(diào)用的該類型的方法。這些方法不會訪問序列化流,而是允許您在序列化或反序列化之前和之后更改對象。屬性可以應用于類型繼承層次結(jié)構(gòu)的所有級別,每種方法在層次結(jié)構(gòu)中從基礎(chǔ)到派生程度最大依次調(diào)用。此機制通過將序列化和反序列化的職責分配給派生程度最大的實現(xiàn),可以避免實現(xiàn)ISerializable接口的復雜性以及可能產(chǎn)生的任何問題。此外,此機制還允許格式化程序忽略字段的填充以及從序列化流中的檢索。有關(guān)控制序列化和反序列化的詳細信息和示例,請單擊上面的任意鏈接。此外,在向現(xiàn)有可序列化類型中添加新字段時,將OptionalFieldAttribute屬性應用于該字段。在處理缺少新字段的流時,BinaryFormatter和SoapFormatter將忽略該字段的不存在。實現(xiàn)ISerializable接口控制序列化的一種方式是在對象上實現(xiàn)ISerializable接口。但是應注意,在控制序列化時,上一節(jié)中的方法優(yōu)先于此方法。此外,對于用Serializable屬性標記且在類級別上或其構(gòu)造函數(shù)上具有聲明性或命令性安全的類,不應使用默認序列化。相反,這些類應始終實現(xiàn)ISerializable接口。實現(xiàn)ISerializable涉及實現(xiàn)GetObjectData方法以及在反序列化對象時使用的特殊構(gòu)造函數(shù)。以下示例代碼說明如何對前面節(jié)中的MyObject類實現(xiàn)ISerializable。C# 復制代碼[Serializable]publicclassMyObject:ISerializable(publicintn1;publicintn2;publicStringstr;publicMyObject()(}

protectedMyObject(SerializationInfoinfo,StreamingContextcontext)(n1=info.GetInt32(〃i〃);n2=info.GetInt32(〃j〃);str=info.GetString(〃k〃);}[SecurityPermissionAttribute(SecurityAction.Demand,SerializationFormatter=true)]publicvirtualvoidGetObjectData(SerializationInfoinfo,StreamingContextcontext)(info.AddValue(〃i〃,n1);info.AddValue(〃j〃,n2);info.AddValue(〃k〃,str);}}當序列化期間調(diào)用GetObjectData時,您負責填充由方法調(diào)用提供的SerializationInfo。只需將要被序列化的變量作為名稱/值對添加。任何文本都可用作該名稱。您可以自由決定將哪些成員變量添加到SerializationInfo中,前提是序列化了足夠多的數(shù)據(jù),可以在反序列化期間還原該對象。如果基對象實現(xiàn)了ISerializable,則派生類應對該基對象調(diào)用GetObjectData方法。請注意,序列化可使其他代碼得以查看或修改本來不可訪問的對象實例數(shù)據(jù)。因此,執(zhí)行序列化的代碼要求指定了SerializationFormatter標志的SecurityPermission。在默認策略下,通過Internet下載的代碼或Intranet代碼不會被授予該權(quán)限;只有本地計算機上的代碼才會被授予該權(quán)限。必須對GetObjectData方法進行顯式保護,方法是要求指定了SerializationFormatter標志的SecurityPermission或要求其他專門保護私有數(shù)據(jù)的權(quán)限。如果私有字段中存儲了敏感信息,應要求GetObjectData具有適當權(quán)限,以保護數(shù)據(jù)。請記住,被授予指定了SerializationFormatter標志的SecurityPermission的代碼可以查看和修改存儲在私有字段中的數(shù)據(jù)。被授予了此SecurityPermission的惡意調(diào)用方可以查看隱藏目錄位置或授予的權(quán)限等數(shù)據(jù),并使用這些數(shù)據(jù)攻擊計算機的安全漏洞。有關(guān)可以指定的安全權(quán)限標志的完整列表,請參見SecurityPermissionFlag枚舉。有一點必須強調(diào),在向類中添加ISerializable時,必須實現(xiàn)GetObjectData和特殊構(gòu)造函數(shù)。如果缺少GetObjectData,編譯器將發(fā)出警告。但是,由于無法強制實現(xiàn)構(gòu)造函數(shù),因此如果缺少構(gòu)造函數(shù),編譯器不會發(fā)出警告;并且當試圖反序列化不帶構(gòu)造函數(shù)的類時,會引發(fā)異常。當前的設(shè)計優(yōu)于SetObjectData方法,可以解決潛在的安全性和版本控制問題。例如,如果SetObjectData方法被定義為接口的一部分,則該方法必須是公共的;這樣,用戶必須編寫代碼以防止多次調(diào)用SetObjectData方法。否則,在執(zhí)行操作的過程中,調(diào)用對象的SetObjectData方法的惡意應用程序會導致潛在的問題。在反序列化期間,使用為此目的提供的構(gòu)造函數(shù)將SerializationInfo傳遞給類。在反序列化對象時,對構(gòu)造函數(shù)施加的任何可見性約束均被忽略,因此可以將類標記為public、protected、internal或private。但是,如果類未被密封,則最好將構(gòu)造函數(shù)標記為protected;如果類被密封了,則應將構(gòu)造函數(shù)標記為private。構(gòu)造函數(shù)還應執(zhí)行徹底的輸入驗證。為了避免惡意代碼的濫用,構(gòu)造函數(shù)應強制使用任何其他構(gòu)造函數(shù)獲取類實例所需的

同樣的安全檢查和權(quán)限。如果不采用此建議,惡意代碼將可以預先序列化對象,通過指定了SerializationFormatter標志的SecurityPermission獲得控制權(quán),然后在客戶端計算機上反序列化對象,避開本來在標準實例構(gòu)造過程中會使用公共構(gòu)造函數(shù)應用的任何安全性。要還原該對象的狀態(tài),只需使用在序列化期間使用的名稱從Serializationinfo檢索變量的值即可。如果基類實現(xiàn)ISerializable,則應調(diào)用基構(gòu)造函數(shù)以允許基對象還原其變量。當您從實現(xiàn)ISerializable的類中派生一個新類時,派生類必須同時實現(xiàn)該構(gòu)造函數(shù)以及GetObjectData方法(如果派生類具有需要序列化的變量)。下面的代碼示例說明如何使用前面所示的MyObject類做到這一點。C# 也復制代碼[Serializable]publicclassObjectTwo:MyObject(publicintnum;publicObjectTwo():base()(}protectedObjectTwo(Serializationinfosi,StreamingContextcontext):base(si,context)(num=si.Getint32(〃num〃);}[SecurityPermissionAttribute(SecurityAction.Demand,SerializationFormatter=true)]publicoverridevoidGetObjectData(Serializationinfosi,StreamingContextcontext)(base.GetObjectData(si,context);si.AddValue(〃num〃,num);}}不要忘記在反序列化構(gòu)造函數(shù)中調(diào)用基類。如果沒有調(diào)用基類,將永遠不會調(diào)用基類上的構(gòu)造函數(shù),并且在反序列化后該對象將不會被完全構(gòu)造。對象將被徹底重新構(gòu)造,并且在反序列化期間調(diào)用方法可能會產(chǎn)生不良的副作用,因為被調(diào)用的方法可能引用在進行此調(diào)用時尚未被反序列化的對象引用。如果反序列化的類實現(xiàn)IDese

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
  • 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論