Použití kontraktů dat

Kontrakt dat je formální smlouva mezi službou a klientem, která abstraktivně popisuje data, která se mají vyměňovat. To znamená, že ke komunikaci nemusí klient a služba sdílet stejné typy, pouze stejné datové kontrakty. Kontrakt dat přesně definuje, pro každý parametr nebo návratový typ, jaká data se serializují (převést na XML), které se mají vyměňovat.

Základy kontraktů dat

Windows Communication Foundation (WCF) používá serializační modul nazývaný Serializátor kontraktu dat ve výchozím nastavení serializovat a deserializovat data (převést na a z XML). Všechny primitivní typy rozhraní .NET Framework, jako jsou celá čísla a řetězce, a také určité typy, které jsou považovány za primitivy, například DateTime a XmlElement, lze serializovat bez další přípravy a jsou považovány za s výchozími kontrakty dat. Mnoho typů rozhraní .NET Framework má také existující datové kontrakty. Úplný seznam serializovatelných typů naleznete v části Typy podporované serializátorem kontraktu dat.

Nové komplexní typy, které vytvoříte, musí mít definovaný kontrakt dat, aby se daly serializovat. Ve výchozím nastavení DataContractSerializer odvodí kontrakt dat a serializuje všechny veřejně viditelné typy. Všechny veřejné vlastnosti pro čtení a zápis a pole typu jsou serializovány. Členy můžete od serializace odhlásit pomocí nástroje IgnoreDataMemberAttribute. Kontrakt dat můžete také explicitně vytvořit pomocí DataContractAttribute a DataMemberAttribute atributů. To se obvykle provádí použitím DataContractAttribute atributu na typ. Tento atribut lze použít pro třídy, struktury a výčty. Atribut DataMemberAttribute se pak musí použít u každého člena datového typu kontraktu, aby bylo možné označit, že se jedná o datový člen, to znamená, že by měl být serializován. Další informace naleznete v tématu Serializovatelné typy.

Příklad

Následující příklad ukazuje kontrakt služby (rozhraní), ke kterému ServiceContractAttribute byly explicitně použity atributy OperationContractAttribute . Příklad ukazuje, že primitivní typy nevyžadují kontrakt dat, zatímco složitý typ dělá.

[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

Následující příklad ukazuje, jak je vytvořen datový kontrakt pro MyTypes.PurchaseOrder typ použitím DataContractAttribute a atributů třídy a DataMemberAttribute jejích členů.

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

Notes

Následující poznámky obsahují položky, které je potřeba vzít v úvahu při vytváření kontraktů dat:

  • Atribut IgnoreDataMemberAttribute je dodržen pouze při použití s neoznačenými typy. To zahrnuje typy, které nejsou označeny jedním z DataContractAttribute, SerializableAttribute, CollectionDataContractAttributenebo EnumMemberAttribute atributů, nebo označeny jako serializovatelné jinými prostředky (například IXmlSerializable).

  • Atribut můžete použít DataMemberAttribute u polí a vlastností.

  • Úrovně přístupnosti členů (interní, soukromé, chráněné nebo veřejné) nemají žádný vliv na kontrakt dat.

  • Atribut DataMemberAttribute se ignoruje, pokud se použije u statických členů.

  • Během serializace je volán kód property-get pro členy dat vlastností získat hodnotu vlastností, které mají být serializovány.

  • Během deserializace je nejprve vytvořen neinicializovaný objekt bez volání konstruktorů typu. Pak jsou všechny datové členy deserializovány.

  • Během deserializace se kód sady vlastností volá pro členy dat vlastností k nastavení vlastností na hodnotu deserializovat.

  • Aby byl datový kontrakt platný, musí být možné serializovat všechny jeho datové členy. Úplný seznam serializovatelných typů naleznete v části Typy podporované serializátorem kontraktu dat.

    Obecné typy se zpracovávají úplně stejně jako obecné typy. Pro obecné parametry neexistují žádné zvláštní požadavky. Představte si například následující typ.

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

Tento typ je serializovatelný, zda typ použitý pro parametr obecného typu (T) je serializovatelný nebo ne. Vzhledem k tomu, že musí být možné serializovat všechny datové členy, následující typ je serializovatelný pouze v případě, že je parametr obecného typu také serializovatelný, jak je znázorněno v následujícím kódu.

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

Kompletní ukázka kódu služby WCF, která definuje kontrakt dat, naleznete v ukázce základního kontraktu dat.

Viz také