| 合約類型 | CLR 構件 | 屬性 | 中立表示 |
| 服務合約 | 介面 | [ServiceContract]、[OperationContract] | WSDL (portType、binding、port) |
| 資料合約 | 類別/結構 | [DataContract]、[DataMember] | XSD (complexType、element) |
資料合約轉換範例
CLR 型別 (服務端)
[DataContract(Namespace = "https://artech.datacontractversioning")]
public class Order
{
[DataMember(Order = 0)] public Guid OrderID { get; set; }
[DataMember(Order = 1)] public DateTime OrderDate { get; set; }
[DataMember(Order = 2)] public Guid SupplierID { get; set; }
}
中立 XSD (服務公開)
<xs:schema targetNamespace="https://artech.datacontractversioning" ...>
<xs:complexType name="Order">
<xs:sequence>
<xs:element name="OrderID" type="ser:guid" minOccurs="0"/>
<xs:element name="OrderDate" type="xs:dateTime" minOccurs="0"/>
<xs:element name="SupplierID" type="ser:guid" minOccurs="0"/>
</xs:sequence>
</xs:complexType>
<xs:element name="Order" nillable="true" type="tns:Order"/>
</xs:schema>
用戶端 Proxy 類別 (自動產生)
[DataContract(Name = "Order", Namespace = "https://artech.datacontractversioning")]
public partial class Order : IExtensibleDataObject, INotifyPropertyChanged
{
[DataMember(Order = 0)] public Guid OrderID { get; set; }
[DataMember(Order = 1)] public DateTime OrderDate { get; set; }
[DataMember(Order = 2)] public Guid SupplierID { get; set; }
public ExtensionDataObject ExtensionData { get; set; }
// PropertyChanged 實作...
}
資料合約的雙重功能
- 曝光功能:將 CLR 型別轉換為中立合約 (服務端)。
- 適配功能:將現有 CLR 型別對應至既定中立合約 (用戶端)。
兩者本質等價:透過屬性參數 (Name、Namespace、Order、IsRequired、EmitDefaultValue) 控制對應關係。
對應機制實例:CustomOrder 適配 Order 合約
用戶端原有型別
public class CustomOrder
{
public Guid OrderNo { get; set; }
public Guid SupplierNo { get; set; }
public DateTime OrderDate { get; set; }
}
差異分析
| 層面 | 服務端 Order | 用戶端 CustomOrder |
| 類別名稱 | Order | CustomOrder |
| 命名空間 | https://artech.datacontractversioning | 無 (預設) |
| 成員名稱 | OrderID, OrderDate, SupplierID | OrderNo, OrderDate, SupplierNo |
| 成員順序 | 0, 1, 2 | 無指定 |
透過屬性完成適配
[DataContract(Name = "Order", Namespace = "https://artech.datacontractversioning")]
public class CustomOrder
{
[DataMember(Order = 0, Name = "OrderID")] public Guid OrderNo { get; set; }
[DataMember(Order = 2, Name = "SupplierID")] public Guid SupplierNo { get; set; }
[DataMember(Order = 1)] public DateTime OrderDate { get; set; }
[DataMember(Order = 3)] public string ShippingAddress { get; set; }
}
關鍵屬性:
DataContract.Name、Namespace:對應 XSD complexType name、targetNamespace
DataMember.Name:對應 XSD element name
DataMember.Order:對應 XSD sequence 順序
核心屬性速查表
| 屬性 | 適用目標 | 關鍵參數 | 說明 |
| [DataContract] | 類別/結構 | Name, Namespace, IsReference | 定義資料合約根結構 |
| [DataMember] | 欄位/屬性 | Name, Order, IsRequired, EmitDefaultValue | 定義資料成員,預設 IsRequired=false |
| [EnumMember] | 列舉值 | Value | 控制列舉序列化名稱 |
| [CollectionDataContract] | 集合類別 | Name, Namespace, ItemName | 自訂集合序列化呈現 |
| [KnownType] | 類別/作業 | Type, Method | 宣告衍生型別,支援多型序列化 |
開發模式選擇
- 共用組件模式:WCF-WCF 專案,共用定義合約的組件,最直接、效能最佳。
- Proxy 產生模式:異構用戶端,透過
Add Service Reference / Svcutil.exe 產生 Proxy。
- 手工適配模式:用戶端已有領域模型,需對應既有服務合約,彈性最高。
結語
資料合約是 WCF 連結 .NET 型別系統與 XML 結構描述的橋樑。掌握屬性對應機制,能靈活處理版本演進、異構整合與領域模型映射。後續文章將深入探討泛型、集合、版本控制等進階主題。
- 上一篇文章: 談 WCF Data Contract (二):泛型型別的序列化支援與命名策略
- 下一篇文章: Web Services:建構 Microsoft .NET 平台的基石
Copyright ©
程式碼之家 All Rights Reserved