使用 XmlSerializer 類別

Windows Communication Foundation (WCF) 可以使用兩種不同的序列化技術,將您應用程式中的資料轉換成 XML,在用戶端和服務之間傳輸,這種處理稱為序列化。

DataContractSerializer 為預設值

根據預設,WCF 會使用 DataContractSerializer 類別來序列化資料型別。這個序列化程式支援下列型別:

許多 .NET Framework 型別屬於後兩種類別,因此是可序列化的。可序列化型別的陣列也是可序列化的。如需完整的清單,請參閱指定服務合約中的資料傳輸

搭配資料合約類型使用的 DataContractSerializer 是寫入新 WCF 服務的建議方式。如需詳細資訊,請參閱 使用資料合約

何時使用 XmlSerializer 類別

WCF 也支援 XmlSerializer 類別。XmlSerializer 不是 WCF 特有的類別,它是 ASP.NET Web 服務使用的同一個序列化引擎。XmlSerializer 類別支援的型別集範圍比 DataContractSerializer 類別小多了,但允許對於結果 XML 有更多的控制權,並支援更多的 XML 結構描述定義語言 (XSD) 標準。它在可序列化型別上也不需要任何宣告式屬性。如需詳細資訊,請參閱 .NET Framework 文件中的「XML 序列化」主題。XmlSerializer 類別不支援資料合約類型。

當使用 Svcutil.exe 或 Visual Studio 中的「加入服務參考」功能來產生協力廠商服務的用戶端程式碼,或存取協力廠商結構描述時,會自動為您選擇適當的序列化程式。如果結構描述與 DataContractSerializer 不相容,便會選擇 XmlSerializer

手動切換至 XmlSerializer

有時候,您可能必須手動切換至 XmlSerializer。例如,這會發生在下列案例中:

  • 將應用程式從 ASP.NET Web 服務移轉到 WCF 時,您可能會想要重複使用現有的、與 XmlSerializer 相容的型別,來取代建立新的資料合約類型。
  • 當出現在訊息中 XML 的精確控制權很重要,但 Web 服務描述語言 (WSDL) 文件無法使用時,例如,當使用必須符合與 DataContractSerializer 不相容的特定標準化、已發行的結構描述來建立服務時。
  • 當建立遵循舊版 SOAP 編碼標準的服務時。

在這些案例和其他案例中,您可以將 XmlSerializerFormatAttribute 屬性套用至您的服務,以手動切換至 XmlSerializer 類別,如下列程式碼所示。

安全性考量

ms733901.note(zh-tw,VS.90).gif注意:
當切換序列化引擎時,小心是很重要的。根據所使用的序列化程式,相同的型別可以序列化為不同的 XML。如果您不小心使用到錯誤的序列化程式,您可能會將您不想洩露的型別資訊洩露出來。

例如,當序列化資料合約類型時,DataContractSerializer 類別只會序列化以 DataMemberAttribute 屬性標示的成員。XmlSerializer 類別會序列化 Public 成員。請參閱下列程式碼中的型別。

如果型別不慎用於已選擇 XmlSerializer 類別的服務合約中,便會序列化原先可能不想處理的 creditCardNumber 成員。

即使 DataContractSerializer 類別是預設值,您仍然可以將 DataContractFormatAttribute 屬性套用至服務合約類型,明確地為服務選擇該類別 (雖然永遠不會有這個需要)。

用於此服務的序列化程式是合約的重要部分,且無法藉由選擇不同的繫結或變更其他組態設定來改變。

其他重要的安全性考量適用於 XmlSerializer 類別。第一,強烈建議任何使用 XmlSerializer 類別的 WCF 應用程式都要使用受保護不會洩漏的金鑰來簽章。這個建議適用於執行手動切換至 XmlSerializer 時,以及 (由 Svcutil.exe、「加入服務參考」或類似工具) 執行自動切換時。這是因為只要以和應用程式相同的金鑰來簽章,XmlSerializer 序列化引擎就會支援「預先產生的序列化組件」(Pre-generated Serialization Assembly) 的載入。未簽章的應用程式完全不受保護,如果惡意組件符合放在應用程式資料夾或全域組件快取中預先產生之序列化組件的預期名稱,便可能會受到攻擊。當然,攻擊者必須先取得這兩個位置其中之一的寫入存取權,才能嘗試這個動作。

另一個每當您使用 XmlSerializer 時都會存在的威脅,是與系統暫存資料夾有關的寫入存取權。XmlSerializer 序列化引擎會建立並使用這個資料夾中的「序列化組件」(Serialization Assembly)。您應該知道,暫存資料夾的任何寫入存取處理都可能會使用惡意程式碼來覆寫這些序列化組件。

XmlSerializer 支援的規則

您無法將與 XmlSerializer 相容的屬性直接套用至合約作業參數或傳回值。然而,可以將它們套用至具型別的訊息 (訊息合約本文部分),如下列程式碼所示。

當套用至具型別的訊息成員時,這些屬性會覆寫在具型別的訊息屬性上有衝突的屬性。例如,在下列程式碼中,ElementName 會覆寫 Name

當使用 XmlSerializer 時,不支援 MessageHeaderArrayAttribute 屬性。

ms733901.note(zh-tw,VS.90).gif注意:
在這個案例中,XmlSerializer 擲回下列例外狀況,它是在 WCF 之前釋出的:「在結構描述最上層宣告的項目 (Element) 不可以擁有 maxOccurs > 1。經由使用 XmlArrayXmlArrayItem,而不使用 XmlElementAttribute,或使用 Wrapped 參數樣式,來提供 "more" 的包裝函式項目」。

如果您收到此類例外狀況,請查看這種情況是否適用。

WCF 不支援訊息合約和作業合約中的 SoapIncludeAttributeXmlIncludeAttribute 屬性;請改用 KnownTypeAttribute 屬性。

請參閱

工作

HOW TO:使用 XmlSerializer 改善 WCF 用戶端應用程式的啟動時間

參考

DataContractFormatAttribute
DataContractSerializer
XmlSerializer
MessageHeaderArrayAttribute

概念

指定服務合約中的資料傳輸
使用資料合約