語言

使用數據合約

數據合約是服務與客戶端之間的正式合約,其會以抽象方式描述要交換的數據。 也就是說,若要通訊,客戶端和服務不需要共用相同的類型,只有相同的數據合約。 資料合約會針對每個參數或傳回類型,精確定義被序列化(轉換成 XML)來交換的資料。

數據合約基本概念

Windows Communication Foundation (WCF) 預設會使用稱為「資料契約序列化工具」的序列化引擎來序列化及反序列化資料(將資料轉換成 XML 或從 XML 轉換)。 所有 .NET Framework 基本類型,例如整數和字串,以及視為基本類型的特定類型,例如 DateTime 和 XmlElement,都可以以沒有其他準備進行串行化,並被視為具有默認數據合約。 許多 .NET Framework 類型也有現有的數據合約。 如需可串行化類型的完整清單,請參閱 數據合約串行化程式支援的類型。

您建立的新複雜型別必須定義數據合約,才能串行化。 根據預設,會 DataContractSerializer 推斷數據合約,並串行化所有公開可見的類型。 型別的所有公用讀取/寫入屬性和欄位都會被序列化。 您可以使用 IgnoreDataMemberAttribute 來取消成員的序列化。 您也可以使用 DataContractAttribute 和 DataMemberAttribute 屬性明確建立數據合約。 這通常是藉由將 DataContractAttribute 屬性套用至類型來完成。 這個屬性可以套用至類別、結構和列舉。 DataMemberAttribute然後,屬性必須套用至數據合約類型的每個成員,以指出它是數據成員,也就是說,它應該串行化。 如需詳細資訊,請參閱 可串行化類型。

範例

下列範例顯示已明確套用ServiceContractAttribute和OperationContractAttribute屬性的服務合約(介面)。 此範例顯示基本型別不需要資料合約,而複雜型別則為 。

[ServiceContract]
public interface ISampleInterface
{
    // No data contract is required since both the parameter
    // and return types are primitive types.
    [OperationContract]
    double SquareRoot(int root);

    // No Data Contract required because both parameter and return
    // types are marked with the SerializableAttribute attribute.
    [OperationContract]
    System.Drawing.Bitmap GetPicture(System.Uri pictureUri);

    // The MyTypes.PurchaseOrder is a complex type, and thus
    // requires a data contract.
    [OperationContract]
    bool ApprovePurchaseOrder(MyTypes.PurchaseOrder po);
}
<ServiceContract()> _
Public Interface ISampleInterface
    ' No data contract is required since both the parameter and return 
    ' types are both primitive types.
    <OperationContract()> _
    Function SquareRoot(ByVal root As Integer) As Double

    ' No Data Contract required because both parameter and return 
    ' types are marked with the SerializableAttribute attribute.
    <OperationContract()> _
    Function GetPicture(ByVal pictureUri As System.Uri) As System.Drawing.Bitmap

    ' The MyTypes.PurchaseOrder is a complex type, and thus 
    ' requires a data contract.
    <OperationContract()> _
    Function ApprovePurchaseOrder(ByVal po As MyTypes.PurchaseOrder) As Boolean
End Interface

下列範例示範如何透過將 MyTypes.PurchaseOrder 及 DataContractAttribute 屬性套用到類別及其成員來建立 DataMemberAttribute 型別的資料合約。

namespace MyTypes
{
    [DataContract]
    public class PurchaseOrder
    {
        private int poId_value;

        // Apply the DataMemberAttribute to the property.
        [DataMember]
        public int PurchaseOrderId
        {

            get { return poId_value; }
            set { poId_value = value; }
        }
    }
}
Namespace MyTypes
    <System.Runtime.Serialization.DataContractAttribute()> _
    Public Class PurchaseOrder
        Private poId_value As Integer

        ' Apply the DataMemberAttribute to the property.

        <DataMember()> _
        Public Property PurchaseOrderId() As Integer

            Get
                Return poId_value
            End Get
            Set
                poId_value = value
            End Set
        End Property
    End Class
End Namespace

註釋

下列附注提供建立資料契約時要考慮的事項:

  • IgnoreDataMemberAttribute 屬性只有在搭配未標記的類型時才會生效。 這包括類型未使用DataContractAttribute、SerializableAttribute、CollectionDataContractAttribute或EnumMemberAttribute屬性標記,或以任何其他方式(例如IXmlSerializable)標示為可串行化的。

  • 您可以將DataMemberAttribute屬性套用至欄位和屬性。

  • 成員存取層級(內部、私有、受保護或公共)不會以任何方式影響資料契約。

  • DataMemberAttribute如果屬性套用至靜態成員,則會予以忽略。

  • 在串行化期間,會針對屬性數據成員呼叫 property-get 程式代碼,以取得要串行化之屬性的值。

  • 在反序列化過程中,會先建立一個未經初始化的物件,並且不會在該型別上呼叫任何建構函式。 然後所有資料成員都會被反序列化。

  • 在還原串行化期間,會呼叫屬性集程式代碼,讓屬性數據成員將屬性設定為要還原串行化的值。

  • 若要讓數據合約有效,必須能夠串行化其所有數據成員。 如需可串行化類型的完整清單,請參閱 數據合約串行化程式支援的類型。

    泛型型別的處理方式與非泛型型別完全相同。 泛型參數沒有特殊需求。 例如,請考慮下列類型。

[DataContract]
public class MyGenericType1<T>
{
    // Code not shown.
}
<DataContract()> _
Public Class MyGenericType1(Of T)
    ' Code not shown.
End Class

無論用於泛型類型參數的T類型是否可序列化,此類型始終是可序列化的。 因為必須能夠串行化所有數據成員,所以只有在泛型型別參數也是可串行化時,才能串行化下列類型,如下列程式碼所示。

[DataContract]
public class MyGenericType2<T>
{
    [DataMember]
    T theData;
}
<DataContract()> _
Public Class MyGenericType2(Of T)
    <DataMember()> _
    Dim theData As T
End Class

如需定義數據合約之 WCF 服務的完整程式碼範例,請參閱 基本數據合約 範例。

另請參閱