Sdílet prostřednictvím


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. Datový kontrakt přesně definuje, pro každý parametr nebo návratový typ, jaká data se serializují (převedena na XML) k výměně.

Základy kontraktů dat

Windows Communication Foundation (WCF) ve výchozím nastavení používá serializační modul s názvem Serializátor datových smluv k serializaci a deserializaci dat (převodu na XML 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í), na které byly atributy ServiceContractAttribute a OperationContractAttribute explicitně použity. Příklad ukazuje, že primitivní typy nevyžadují datovou smlouvu, zatímco složitý typ ji vyžaduje.

[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 typ MyTypes.PurchaseOrder použitím atributů DataContractAttribute a DataMemberAttribute na třídu a její členy.

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

Poznámky

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 pro datové členy vlastností volán kód property-get, který získává hodnotu vlastností, jež 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 je volán kód pro nastavení vlastností pro datové členy, aby se nastavily na hodnoty, které jsou deserializovány.

  • 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 neobecné 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é