共用方式為


XML 序列化

序列化是將物件轉換成可輕易傳輸的形式。 例如,您可以使用用戶端與伺服器之間的 HTTP,將物件串行化並透過因特網傳輸。 另一方面,反序列化會從數據流重新建構物件。

XML 串行化只會將物件的公用欄位和屬性值串行化成 XML 資料流。 XML 串行化不包含類型資訊。 例如,如果您的 Book 物件存在於 Library 命名空間中,則不保證它會還原串行化為相同類型的物件。

備註

XML 串行化不會轉換方法、索引器、私用字段或只讀屬性(只讀集合除外)。 若要串行化所有物件的欄位和屬性,無論是公用還是私用,請使用 DataContractSerializer 而不是 XML 串行化。

XML 串行化中的中央類別是 XmlSerializer 類別,而這個類別中最重要的方法是 SerializeDeserialize 方法。 XmlSerializer 會建立 C# 檔案,並將其編譯成 .dll 檔案,以執行此序列化。 XML 串行化程式產生器工具 (Sgen.exe) 的設計目的是要事先與您的應用程式一起部署這些串行化元件,並改善啟動效能。 XmlSerializer 所產生的 XML 數據流符合萬維網聯合會 (W3C) XML 架構定義語言 (XSD) 1.0 建議。 此外,產生的數據類型與標題為「XML 架構第 2 部分:數據類型」的檔相容。

對象中的數據會使用程式設計語言建構來描述,例如類別、欄位、屬性、基本類型、陣列,甚至以 XmlElementXmlAttribute 物件的形式內嵌的 XML。 您可以選擇建立自己的類別、以屬性加上批註,或使用 XML 架構定義工具來根據現有的 XML 架構產生類別。

如果您有 XML 架構,您可以執行 XML 架構定義工具來產生一組與架構強類型化的類別,並附有屬性註釋。 當這類類別的實例串行化時,產生的 XML 會遵守 XML 架構。 透過這類類別,您可以針對容易作的物件模型進行程式設計,同時確保產生的 XML 符合 XML 架構。 這是使用 .NET 中其他類別的替代方法,例如 XmlReaderXmlWriter 類別,以剖析和寫入 XML 數據流。 如需詳細資訊,請參閱 XML 檔和數據。 這些類別可讓您剖析任何 XML 資料流。 相反地,當 XML 數據流預期符合已知的 XML 架構時,請使用 XmlSerializer

屬性可控制 XmlSerializer 類別所產生的 XML 數據流,讓您能夠設定 XML 資料流的 XML 命名空間、專案名稱、屬性名稱等等。 如需這些屬性及其控制 XML 串行化方式的詳細資訊,請參閱 使用屬性控制 XML 串行化。 如需用來控制所產生 XML 之屬性的數據表,請參閱 控制 XML 串行化的屬性

XmlSerializer 類別可以進一步串行化物件,併產生編碼的SOAP XML資料流。 產生的 XML 遵守萬維網聯盟檔的第 5 節,標題為「簡單物件存取通訊協定 (SOAP) 1.1」。如需此程式的詳細資訊,請參閱 如何:將物件串行化為 SOAP-Encoded XML 數據流。 如需控制所產生 XML 之屬性的數據表,請參閱 控制編碼 SOAP 串行化的屬性

XmlSerializer 類別會產生由 XML Web 服務建立並傳遞至的 SOAP 訊息。 若要控制SOAP訊息,您可以將屬性套用至 XML Web 服務檔案 (.asmx) 中找到的類別、傳回值、參數和欄位。 您可以使用「控制 XML 串行化的屬性」和「控制編碼 SOAP 串行化的屬性」中列出的屬性,因為 XML Web 服務可以使用常值或編碼的 SOAP 樣式。 如需使用屬性來控制 XML Web 服務所產生的 XML 的詳細資訊,請參閱 使用 XML Web 服務進行 XML 串行化。 如需SOAP和 XML Web 服務的詳細資訊,請參閱 自定義SOAP訊息格式設定。

XmlSerializer 應用程式的安全性考慮

建立使用 XmlSerializer 的應用程式時,請注意下列專案及其含意:

  • XmlSerializer 會建立 C# (.cs) 檔案,並將其編譯成 TEMP 環境變數所命名目錄中 .dll 檔案;串行化會與那些 DLL 一起發生。

    備註

    這些串行化元件可以事先產生,並使用 SGen.exe 工具簽署。 這不適用於 Web 服務的伺服器上。 換句話說,它只適用於用戶端使用和手動串行化。

    建立和編譯時,程式代碼和 DLL 很容易受到惡意程序的攻擊。 有兩個以上的使用者可以共用 TEMP 目錄。 如果兩個帳戶具有不同的安全性許可權,且高許可權帳戶使用 XmlSerializer 執行應用程式,共用 TEMP 目錄會很危險。 在此情況下,一位使用者可以取代已編譯的.cs或 .dll 檔案,來入侵計算機的安全性。 若要消除此顧慮,請務必確保電腦上的每個帳戶都有自己的使用者設定檔。 根據預設,TEMP 環境變數會指向每個帳戶的不同目錄。

  • 如果惡意使用者將 XML 數據的連續串流傳送至網頁伺服器(阻斷服務攻擊), XmlSerializer 會繼續處理數據,直到計算機在資源不足為止。

    如果您使用執行 Internet Information Services (IIS) 的電腦,而且您的應用程式是在 IIS 內執行,就會消除這種攻擊。 IIS 具有不會處理超過設定數量之數據流的閘道(預設值為 4 KB)。 如果您建立的應用程式未使用 IIS 並使用 XmlSerializer 進行反序列化,您應該實作類似的保護措施,以防止阻斷服務攻擊。

  • XmlSerializer 會使用提供給數據的任何類型來串行化數據並執行任何程序代碼。

    惡意對象呈現威脅的方式有兩種。 它可以執行惡意代碼,也可以將惡意代碼插入 XmlSerializer 所建立的 C# 檔案中。 在第二個案例中,惡意物件可能會以某種方式將程序代碼插入 XmlSerializer 所建立的 C# 檔案中。 雖然此問題已徹底檢查過,但這類攻擊被認為不太可能,但您應該採取一律不要以未知且不受信任的類型串行化數據的預防措施。

  • 串行化敏感數據可能易受攻擊。

    XmlSerializer 串行化數據之後,它可以儲存為 XML 檔案或其他數據存放區。 如果您的資料存放區可供其他進程使用,或顯示在內部網路或因特網上,則數據可能會遭竊並惡意使用。 例如,如果您建立應用程式來串行化包含信用卡號碼的訂單,則數據會高度敏感。 為了協助避免這種情況,請一律保護數據的存放區,並採取步驟將它保持私人。

簡單類別的串行化

下列程式代碼範例顯示具有公用欄位的基本類別。

Public Class OrderForm
    Public OrderDate As DateTime
End Class
public class OrderForm
{
    public DateTime OrderDate;
}

當這個類別的實例串行化時,它可能會像下面這樣。

<OrderForm>
    <OrderDate>12/12/01</OrderDate>
</OrderForm>

如需串行化的詳細資訊,請參閱 XML 串行化範例

可序列化的項目

您可以使用 XmlSerializer 類別串行化下列專案:

  • 公用類別的讀取/寫入屬性和欄位。

  • 實作 ICollectionIEnumerable 的類別。

    備註

    只有集合會被序列化,而公有屬性則不會。

  • XmlElement 物件。

  • XmlNode 物件。

  • DataSet 物件。

如需串行化或還原串行化對象的詳細資訊,請參閱 如何:串行化物件如何:還原串行化物件

使用 XML 串行化的優點

XmlSerializer 類別可讓您在將物件串行化為 XML 時完成且有彈性的控制。 如果您要建立 XML Web 服務,您可以將控制串行化的屬性套用至類別和成員,以確保 XML 輸出符合特定的架構。

例如, XmlSerializer 可讓您:

  • 指定欄位或屬性應編碼為屬性或元素。

  • 指定要使用的 XML 命名空間。

  • 如果欄位或屬性名稱不合適,請指定項目或屬性的名稱。

XML 串行化的另一個優點是,只要產生的 XML 數據流符合指定的架構,您就對所開發的應用程式沒有任何條件約束。 想像一下用來描述書籍的架構。 它具有標題、作者、發行者和 ISBN 數字元素。 您可以開發應用程式,以您所需的方式處理 XML 數據,例如,作為書籍訂單或作為書籍庫存。 不論是哪一種情況,唯一的需求是 XML 數據流符合指定的 XML 架構定義語言 (XSD) 架構。

XML 串行化考慮

使用 XmlSerializer 類別時,應考慮下列事項:

  • Sgen.exe 工具專門設計用於生成序列化組件,以獲得最佳效能。

  • 串行化的數據只包含數據本身和類別的結構。 不包含類型識別和元件資訊。

  • 只有公用屬性和欄位可以被序列化。 屬性必須有公用存取子(get 和 set 方法)。 如果您必須串行化非公用數據,請使用 DataContractSerializer 類別而非 XML 串行化。

  • 類別必須有 XmlSerializer 串行化的無參數建構函式。

  • 無法序列化方法。

  • 如果符合特定需求,XmlSerializer 可以對實作 IEnumerableICollection 的類別進行不同處理,如下所示。

    實作 IEnumerable 的 類別必須實作採用單一參數的公用 Add 方法。 Add 方法的參數必須與從 GetEnumerator 方法傳回的 IEnumerator.Current 屬性所傳回的類型一致(多型)。

    除了 IEnumerable (例如 CollectionBase) 之外,實作 ICollection 的類別必須具有接受整數的公用 Item 索引屬性(C# 中的索引器),而且必須具有整數類型的公用 Count 屬性。 傳遞至 Add 方法的參數必須與 從 Item 屬性傳回的型別相同,或是該類型基底的其中一個。

    對於實作 ICollection 的類別,要串行化的值會從索引 的 Item 屬性擷取,而不是藉由呼叫 GetEnumerator 來擷取。 此外,公用欄位和屬性不會串行化,但傳回另一個集合類別的公用欄位除外(一個實作 ICollection 的類別)。 如需範例,請參閱 XML 串行化範例

XSD 數據類型對應

標題為 XML 架構第 2 部分:資料類型 的 W3C 檔案會指定 XML 架構定義語言 (XSD) 架構中允許的簡單資料類型。 針對其中許多專案(例如 intdecimal),.NET 中有對應的數據類型。 不過,某些 XML 數據類型沒有對應的 .NET 數據類型,例如 NMTOKEN 數據類型。 在這種情況下,如果您使用 XML 架構定義工具 (XML 架構定義工具 (Xsd.exe)從架構產生類別,則會將適當的屬性套用至字串類型的成員,而其 DataType 屬性會設定為 XML 數據類型名稱。 例如,如果架構包含名為 「MyToken」 且具有 XML 數據類型 NMTOKEN 的專案,產生的類別可能會包含成員,如下列範例所示。

<XmlElement(DataType:="NMTOKEN")> _
Public MyToken As String
[XmlElement(DataType = "NMTOKEN")]
public string MyToken;

同樣地,如果您要建立必須符合特定 XML 架構的類別(XSD),您應該套用適當的屬性,並將其 DataType 屬性設定為所需的 XML 數據類型名稱。

如需類型對應的完整清單,請參閱下列任何屬性類別的 DataType 屬性:

另請參閱