共用方式為


使用數據合約

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

數據合約基本概念

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

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

範例

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

[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.PurchaseOrderDataContractAttribute 屬性套用到類別及其成員來建立 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 屬性只有在搭配未標記的類型時才會生效。 這包括類型未使用DataContractAttributeSerializableAttributeCollectionDataContractAttributeEnumMemberAttribute屬性標記,或以任何其他方式(例如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 服務的完整程式碼範例,請參閱 基本數據合約 範例。

另請參閱