Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
Affinché un client invii correttamente dati di un determinato tipo a un servizio o a un servizio per inviare correttamente dati a un client, il tipo inviato non deve necessariamente esistere sul lato ricevente. L'unico requisito è che i contratti dati di entrambi i tipi siano equivalenti. A volte, non è necessaria una rigorosa equivalenza, come descritto in Controllo delle versioni del contratto dati.
Affinché i contratti dati siano equivalenti, devono avere lo stesso spazio dei nomi e lo stesso nome. Inoltre, ogni membro dati su un lato deve avere un membro dati equivalente su l'altro lato.
Affinché i membri dati siano equivalenti, devono avere lo stesso nome. Inoltre, devono rappresentare lo stesso tipo di dati; ovvero i contratti dati devono essere equivalenti.
Annotazioni
Si noti che i nomi e i namespace dei contratti dati, nonché i nomi dei membri di dati, fanno distinzione tra maiuscole e minuscole.
Per altre informazioni sui nomi e sugli spazi dei nomi dei contratti dati, nonché sui nomi dei membri dati, vedere Nomi dei contratti dati.
Se esistono due tipi sullo stesso lato (mittente o destinatario) e i relativi contratti dati non sono equivalenti (ad esempio, hanno membri dati diversi), non è consigliabile assegnare loro lo stesso nome e lo stesso spazio dei nomi. In questo modo è possibile che vengano generate eccezioni.
I contratti dati per i tipi seguenti sono equivalenti:
[DataContract]
public class Customer
{
[DataMember]
public string fullName;
[DataMember]
public string telephoneNumber;
}
[DataContract(Name = "Customer")]
public class Person
{
[DataMember(Name = "fullName")]
private string nameOfPerson;
private string address;
[DataMember(Name = "telephoneNumber")]
private string phoneNumber;
}
<DataContract()> _
Public Class Customer
<DataMember()> _
Public fullName As String
<DataMember()> _
Public telephoneNumber As String
End Class
<DataContract(Name:="Customer")> _
Public Class Person
<DataMember(Name:="fullName")> _
Private nameOfPerson As String
Private address As String
<DataMember(Name:="telephoneNumber")> _
Private phoneNumber As String
End Class
Equivalenza dell'ordine dei membri dati e del contratto dati
L'uso della proprietà Order della classe DataMemberAttribute può influire sull'equivalenza del contratto dati. I contratti dati devono avere membri visualizzati nello stesso ordine per essere equivalenti. L'ordine predefinito è alfabetico. Per altre informazioni, vedere Ordine dei membri dati.
Ad esempio, il codice seguente genera contratti dati equivalenti.
[DataContract(Name = "Coordinates")]
public class Coords1
{
[DataMember]
public int X;
[DataMember]
public int Y;
// Order is alphabetical (X,Y).
}
[DataContract(Name = "Coordinates")]
public class Coords2
{
[DataMember]
public int Y;
[DataMember]
public int X;
// Order is alphabetical (X,Y), equivalent
// to the preceding code.
}
[DataContract(Name = "Coordinates")]
public class Coords3
{
[DataMember(Order = 2)]
public int Y;
[DataMember(Order = 1)]
public int X;
// Order is according to the Order property (X,Y),
// equivalent to the preceding code.
}
<DataContract(Name:="Coordinates")> _
Public Class Coords1
<DataMember()> _
Public X As Integer
<DataMember()> _
Public Y As Integer
' Order is alphabetical (X,Y).
End Class
<DataContract(Name:="Coordinates")> _
Public Class Coords2
<DataMember()> _
Public Y As Integer
<DataMember()> _
Public X As Integer
' Order is alphabetical (X,Y), equivalent
' to the preceding code.
End Class
<DataContract(Name:="Coordinates")> _
Public Class Coords3
<DataMember(Order:=2)> _
Public Y As Integer
<DataMember(Order:=1)> _
Public X As Integer
' Order is according to the Order property (X,Y),
' equivalent to the preceding code.
End Class
Tuttavia, quanto segue non comporta un contratto dati equivalente.
[DataContract(Name = "Coordinates")]
public class Coords4
{
[DataMember(Order = 1)]
public int Y;
[DataMember(Order = 2)]
public int X;
// Order is according to the Order property (Y,X),
// different from the preceding code.
}
<DataContract(Name:="Coordinates")> _
Public Class Coords4
<DataMember(Order:=1)> _
Public Y As Integer
<DataMember(Order:=2)> _
Public X As Integer
' Order is according to the Order property (Y,X),
' different from the preceding code.
End Class
Ereditarietà, interfacce e equivalenza del contratto dati
Quando si determina l'equivalenza, un contratto dati che eredita da un altro contratto dati viene considerato come se fosse solo un contratto dati che include tutti i membri dati dal tipo di base. Tenere presente che l'ordine dei membri dati deve corrispondere e che i membri del tipo di base precedono i membri del tipo derivato nell'ordine. Inoltre, se, come nell'esempio di codice seguente, due membri dati hanno lo stesso valore di ordine, l'ordinamento per tali membri dati è alfabetico. Per altre informazioni, vedere Ordine dei membri dati.
Nell'esempio seguente il contratto dati per il tipo Employee equivale al contratto dati per il tipo Worker.
[DataContract]
public class Person
{
[DataMember]
public string name;
}
[DataContract]
public class Employee : Person
{
[DataMember]
public int department;
[DataMember]
public string title;
[DataMember]
public int salary;
}
// Order is "name", "department", "salary", "title"
// (base class first, then alphabetical).
[DataContract(Name = "Employee")]
public class Worker
{
[DataMember(Order = 1)]
public string name;
[DataMember(Order = 2)]
public int department;
[DataMember(Order = 2)]
public string title;
[DataMember(Order = 2)]
public int salary;
}
// Order is "name", "department", "salary", "title"
// (Order=1 first, then Order=2 in alphabetical order),
// which is equivalent to the Employee order}.
<DataContract()> _
Public Class Person
<DataMember()> Public name As String
End Class
<DataContract()> _
Public Class Employee
Inherits Person
<DataMember()> Public department As Integer
<DataMember()> Public title As String
<DataMember()> Public salary As Integer
End class
' Order is "name", "department", "salary", "title"
' (base class first, then alphabetical).
<DataContract(Name:="Employee")> _
Public Class Worker
<DataMember(Order:=1)> _
Public name As String
<DataMember(Order:=2)> _
Public department As Integer
<DataMember(Order:=2)> _
Public title As String
<DataMember(Order:=2)> _
Public salary As Integer
End Class
' Order is "name", "department", "salary", "title"
' (Order=1 first, then Order=2 in alphabetical order),
' which is equivalent to the Employee order}.
Quando si passano parametri e valori restituiti tra un client e un servizio, non è possibile inviare un contratto dati da una classe di base quando l'endpoint ricevente prevede un contratto dati da una classe derivata. Questo è conforme ai principi della programmazione orientata agli oggetti. Nell'esempio precedente non è possibile inviare un oggetto di tipo Person quando è previsto un oggetto Employee .
È possibile inviare un contratto dati da una classe derivata quando è previsto un contratto dati da una classe base, ma solo se l'endpoint ricevente "conosce" il tipo derivato usando .KnownTypeAttribute Per altre informazioni, vedere Tipi noti del contratto dati. Nell'esempio precedente, un oggetto di tipo Employee può essere inviato quando è previsto un oggetto di tipo Person, ma solo se il codice ricevitore usa il KnownTypeAttribute per includerlo nell'elenco di tipi noti.
Quando si passano parametri e valori restituiti tra applicazioni, se il tipo previsto è un'interfaccia, equivale al tipo previsto di tipo Object. Poiché ogni tipo deriva in definitiva da Object, ogni contratto dati deriva infine dal contratto dati per Object. Pertanto, qualsiasi tipo di contratto dati può essere passato quando è prevista un'interfaccia. Sono necessari passaggi aggiuntivi per lavorare correttamente con le interfacce; per altre informazioni, vedere Tipi noti del contratto dati.