Uso di contratti datiUsing Data Contracts

Un contratto dati è un accordo formale tra un servizio e un client che descrive astrattamente i dati da scambiare.A data contract is a formal agreement between a service and a client that abstractly describes the data to be exchanged. Per comunicare, non è necessario che il client e il servizio condividano gli stessi tipi, ma solo gli stessi contratti dati.That is, to communicate, the client and the service do not have to share the same types, only the same data contracts. Un contratto dati definisce con precisione, per ogni parametro o tipo restituito, i dati serializzati (trasformati in XML) che verranno scambiati.A data contract precisely defines, for each parameter or return type, what data is serialized (turned into XML) to be exchanged.

Nozioni fondamentali dei contratti datiData Contract Basics

Windows Communication Foundation (WCF) usa un motore di serializzazione denominato serializzatore dei contratti dati per impostazione predefinita per serializzare e deserializzare i dati (convertendoli in / da XML).Windows Communication Foundation (WCF) uses a serialization engine called the Data Contract Serializer by default to serialize and deserialize data (convert it to and from XML). Tutti i tipi primitivi .NET Framework, ad esempio numeri interi e stringhe, nonché alcuni tipi trattati come primitivi, ad esempio DateTime e XmlElement, può essere serializzato senza ulteriore preparazione e vengono considerate come dotate di contratti dati predefiniti.All .NET Framework primitive types, such as integers and strings, as well as certain types treated as primitives, such as DateTime and XmlElement, can be serialized with no other preparation and are considered as having default data contracts. Inoltre, molti tipi di .NET Framework hanno contratti dati esistenti.Many .NET Framework types also have existing data contracts. Per un elenco completo dei tipi serializzabili, vedere Types Supported by the Data Contract Serializer.For a full list of serializable types, see Types Supported by the Data Contract Serializer.

Per poter essere serializzabili, è necessario che i nuovi tipi complessi creati dispongano di un contratto dati appositamente definito.New complex types that you create must have a data contract defined for them to be serializable. Per impostazione predefinita, tramite DataContractSerializer viene dedotto il contratto dati e vengono serializzati tutti i tipi visibili pubblicamente.By default, the DataContractSerializer infers the data contract and serializes all publicly visible types. Vengono serializzati i campi e le proprietà di lettura/scrittura pubblici del tipo.All public read/write properties and fields of the type are serialized. È possibile rifiutare esplicitamente i membri per la serializzazione tramite IgnoreDataMemberAttribute.You can opt out members from serialization by using the IgnoreDataMemberAttribute. È inoltre possibile creare in modo esplicito un contratto dati utilizzando gli attributi DataContractAttribute e DataMemberAttribute .You can also explicitly create a data contract by using DataContractAttribute and DataMemberAttribute attributes. Ciò viene di norma realizzato applicando l'attributo DataContractAttribute al tipo.This is normally done by applying the DataContractAttribute attribute to the type. Questo attributo può essere applicato a classi, strutture ed enumerazioni.This attribute can be applied to classes, structures, and enumerations. L'attributo DataMemberAttribute deve quindi essere applicato a ogni membro del tipo di contratto dati per indicare che si tratta di un membro dati, ovvero che deve essere serializzato.The DataMemberAttribute attribute must then be applied to each member of the data contract type to indicate that it is a data member, that is, it should be serialized. Per altre informazioni, vedere tipi serializzabili.For more information, see Serializable Types.

EsempioExample

Nell'esempio seguente viene illustrato un contratto di servizio (un'interfaccia) a cui sono stati applicati in modo esplicito gli attributi ServiceContractAttribute e OperationContractAttribute .The following example shows a service contract (an interface) to which the ServiceContractAttribute and OperationContractAttribute attributes have been explicitly applied. Nell'esempio viene mostrato che i tipi primitivi non richiedono un contratto dati, diversamente da un tipo complesso.The example shows that primitive types do not require a data contract, while a complex type does.

[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 

Nell'esempio seguente viene illustrato come creare un contratto dati per il tipo MyTypes.PurchaseOrder creato applicando gli attributi DataContractAttribute e DataMemberAttribute alla classe e ai relativi membri.The following example shows how a data contract for the MyTypes.PurchaseOrder type is created by applying the DataContractAttribute and DataMemberAttribute attributes to the class and its members.

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 

NoteNotes

Nelle note seguenti sono contenuti gli elementi da tenere presenti durante la creazione di contratti dati:The following notes provide items to consider when creating data contracts:

  • L'attributo IgnoreDataMemberAttribute viene accettato solo se utilizzato con tipi non contrassegnati.The IgnoreDataMemberAttribute attribute is only honored when used with unmarked types. Sono inclusi i tipi non contrassegnati con uno degli attributi DataContractAttribute, SerializableAttribute, CollectionDataContractAttributeo EnumMemberAttribute oppure contrassegnati come serializzabili in qualsiasi altro modo (ad esempio IXmlSerializable).This includes types that are not marked with one of the DataContractAttribute, SerializableAttribute, CollectionDataContractAttribute, or EnumMemberAttribute attributes, or marked as serializable by any other means (such as IXmlSerializable).

  • È possibile applicare l'attributo DataMemberAttribute a campi e proprietà.You can apply the DataMemberAttribute attribute to fields, and properties.

  • I livelli di accessibilità ai membri (interno, privato, protetto o pubblico) non influiscono in alcun modo sul contratto dati.Member accessibility levels (internal, private, protected, or public) do not affect the data contract in any way.

  • L'attributo DataMemberAttribute viene ignorato se applicato a membri statici.The DataMemberAttribute attribute is ignored if it is applied to static members.

  • Durante la serializzazione il codice della proprietà get viene chiamato per i membri dati della proprietà per ottenere il valore delle proprietà da serializzare.During serialization, property-get code is called for property data members to get the value of the properties to be serialized.

  • Durante la deserializzazione viene prima creato un oggetto non inizializzato, senza chiamare alcun costruttore per il tipo,During deserialization, an uninitialized object is first created, without calling any constructors on the type. quindi vengono deserializzati tutti i membri dati.Then all data members are deserialized.

  • Durante la deserializzazione il codice della proprietà set viene chiamato per i membri dati della proprietà per impostare le proprietà sul valore in fase di deserializzazione.During deserialization, property-set code is called for property data members to set the properties to the value being deserialized.

  • Perché un contratto dati sia valido, deve essere possibile serializzare tutti i relativi membri dati.For a data contract to be valid, it must be possible to serialize all of its data members. Per un elenco completo dei tipi serializzabili, vedere Types Supported by the Data Contract Serializer.For a full list of serializable types, see Types Supported by the Data Contract Serializer.

    I tipi generici sono gestiti esattamente nello stesso modo dei tipi non generici.Generic types are handled in exactly the same way as non-generic types. Non vi sono requisiti speciali per i parametri generici.There are no special requirements for generic parameters. Si consideri ad esempio il tipo seguente:For example, consider the following type.

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

Il tipo è serializzabile indipendentemente dal fatto che il tipo utilizzato per il parametro di tipo generico (T) sia serializzabile o meno.This type is serializable whether the type used for the generic type parameter (T) is serializable or not. Poiché deve essere possibile serializzare tutti i membri dati, il tipo seguente è serializzabile solo se il parametro di tipo generico è anch'esso serializzabile, come indicato nel codice seguente.Because it must be possible to serialize all data members, the following type is serializable only if the generic type parameter is also serializable, as shown in the following code.

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

Per un esempio di codice completo di un servizio WCF che definisce un contratto dati, vedere l'esempio Basic Data Contract .For a complete code sample of a WCF service that defines a data contract see the Basic Data Contract sample.

Vedere ancheSee also