Menggunakan Kontrak Data

Kontrak data adalah perjanjian formal antara layanan dan klien yang secara abstrak menjelaskan data yang akan ditukar. Artinya, untuk berkomunikasi, klien dan layanan tidak harus berbagi jenis yang sama, hanya perlu kontrak data yang sama. Kontrak data secara tepat mendefinisikan, untuk setiap parameter atau jenis pengembalian, data yang akan diserialkan (diubah menjadi XML) untuk dipertukarkan.

Dasar-Dasar Kontrak Data

Windows Communication Foundation (WCF) menggunakan mesin serialisasi yang disebut Pembuat Serialisasi Kontrak Data secara default untuk membuat serialisasi dan deserialisasi data (mengonversinya ke dan dari XML). Semua .NET Framework jenis primitif, seperti bilangan bulat dan string, serta jenis tertentu yang diperlakukan sebagai primitif, seperti DateTime dan XmlElement, dapat diserialisasikan tanpa persiapan lain dan dianggap memiliki kontrak data default. Banyak jenis .NET Framework juga memiliki kontrak data yang ada. Untuk daftar lengkap jenis yang dapat diserialisasi, lihat Jenis yang Didukung oleh Pembuat Serialisasi Kontrak Data.

Jenis kompleks baru yang Anda buat harus memiliki kontrak data yang ditentukan agar dapat diserialkan. Secara default, DataContractSerializer menyimpulkan kontrak data dan menserialisasikan semua jenis yang terlihat secara publik. Semua properti baca/tulis publik dan bidang jenis diserialisasikan. Anda dapat menolak anggota dari serialisasi dengan menggunakan IgnoreDataMemberAttribute. Anda juga dapat secara eksplisit membuat kontrak data dengan menggunakan atribut DataContractAttribute dan DataMemberAttribute. Ini biasanya dilakukan dengan menerapkan atribut DataContractAttribute ke jenis. Atribut ini dapat diterapkan ke kelas, struktur, dan enumerasi. Atribut DataMemberAttribute kemudian harus diterapkan ke setiap anggota jenis kontrak data untuk menunjukkan bahwa atribut tersebut merupakan anggota data, yang harus diserialisasikan. Untuk informasi selengkapnya, lihat Jenis yang Dapat Diserialisasikan.

Contoh

Contoh berikut menunjukkan kontrak layanan (antarmuka) tempat atribut ServiceContractAttribute dan OperationContractAttribute telah diterapkan secara eksplisit. Contoh menunjukkan bahwa jenis primitif tidak memerlukan kontrak data, sedangkan jenis yang kompleks memerlukannya.

[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

Contoh berikut menunjukkan bagaimana kontrak data untuk jenis MyTypes.PurchaseOrder dibuat dengan menerapkan atribut DataContractAttribute dan DataMemberAttribute ke kelas dan anggotanya.

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

Catatan

Catatan berikut menyediakan item yang perlu dipertimbangkan saat membuat kontrak data:

  • Atribut IgnoreDataMemberAttribute hanya dipatuhi saat digunakan dengan jenis yang tidak ditandai. Ini termasuk jenis yang tidak ditandai dengan atribut DataContractAttribute, SerializableAttribute, CollectionDataContractAttribute, atau EnumMemberAttribute, atau ditandai sebagai dapat diserialisasikan dengan cara lain (seperti IXmlSerializable).

  • Anda dapat menerapkan atribut ke DataMemberAttribute bidang dan properti.

  • Tingkat aksesibilitas anggota (internal, privat, dilindungi, atau publik) tidak memengaruhi kontrak data dengan cara apa pun.

  • Atribut DataMemberAttribute diabaikan jika diterapkan ke anggota statik.

  • Selama serialisasi, kode property-get dipanggil agar anggota data properti bisa mendapatkan nilai properti yang akan diserialkan.

  • Selama deserialisasi, objek yang belum diinisialisasi dibuat terlebih dahulu, tanpa memanggil konstruktor pada jenisnya. Kemudian semua anggota data dideserialisasi.

  • Selama deserialisasi, kode property-set dipanggil agar anggota data properti dapat mengatur properti ke nilai yang dideserialisasi.

  • Agar kontrak data valid, semua anggota data harus dapat diserialisasi. Untuk daftar lengkap jenis yang dapat diserialisasi, lihat Jenis yang Didukung oleh Pembuat Serialisasi Kontrak Data.

    Jenis generik ditangani persis seperti halnya dengan jenis non-generik. Tidak ada persyaratan khusus untuk parameter generik. Sebagai contoh, perhatikan jenis berikut.

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

Jenis ini dapat diserialisasi baik jenis yang digunakan untuk parameter jenis generik (T) dapat diserialisasi atau tidak. Karena semua anggota data harus dapat diserialisasi, jenis berikut hanya dapat diserialisasi jika parameter jenis generik juga dapat diserialisasi, sebagaimana ditunjukkan pada kode berikut.

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

Untuk sampel kode lengkap layanan WCF yang menentukan kontrak data, lihat sampel Kontrak Data Dasar.

Lihat juga