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.
A volte un client e un servizio non condividono gli stessi tipi. Possono comunque passare i dati l'uno all'altro, purché i contratti dati siano equivalenti su entrambi i lati. L'equivalenza del contratto dati si basa sui nomi del contratto dati e dei membri dati e pertanto viene fornito un meccanismo per eseguire il mapping di tipi e membri a tali nomi. In questo argomento vengono illustrate le regole per la denominazione dei contratti dati e il comportamento predefinito dell'infrastruttura windows Communication Foundation (WCF) durante la creazione di nomi.
Regole di base
Le regole di base per la denominazione dei contratti di dati includono:
Un nome di contratto di dati completo è costituito da uno spazio dei nomi e un nome.
I membri dati hanno solo nomi, ma non namespace.
Quando si elaborano contratti dati, l'infrastruttura WCF fa distinzione tra maiuscole e minuscole sia per i namespace che per i nomi dei contratti dati e dei membri dati.
Nomi di spazio del contratto dati
Uno spazio dei nomi del contratto dati ha la forma di un URI (Uniform Resource Identifier). L'URI può essere assoluto o relativo. Per impostazione predefinita, ai contratti dati per un tipo specifico viene assegnato uno spazio dei nomi proveniente dallo spazio dei nomi CLR (Common Language Runtime) di tale tipo.
Per impostazione predefinita, qualsiasi spazio dei nomi CLR specificato (nel formato Clr.Namespace) viene mappato allo spazio dei nomi http://schemas.datacontract.org/2004/07/Clr.Namespace. Per eseguire l'override di questa impostazione predefinita, applicare l'attributo ContractNamespaceAttribute all'intero modulo o assembly. In alternativa, per controllare lo spazio dei nomi del contratto di dati per ciascun tipo, impostare la proprietà di Namespace di DataContractAttribute.
Annotazioni
Lo http://schemas.microsoft.com/2003/10/Serialization spazio dei nomi è riservato e non può essere usato come spazio dei nomi del contratto dati.
Annotazioni
Non è possibile eseguire l'override dello spazio dei nomi predefinito nei tipi di contratti dati che contengono dichiarazioni delegate.
Nomi dei contratti di dati
Il nome predefinito di un contratto dati per un determinato tipo è il nome di tale tipo. Per eseguire l'override dell'impostazione di default, impostare la proprietà Name di DataContractAttribute su un nome alternativo. Le regole speciali per i tipi generici sono descritte in "Data Contract Names for Generic Types" più avanti in questo argomento.
Nomi dei membri dati
Il nome predefinito di un membro dati per un determinato campo o proprietà è il nome di tale campo o proprietà. Per eseguire l'override dell'impostazione predefinita, impostare la proprietà Name di DataMemberAttribute a un valore alternativo.
Esempi
Nell'esempio seguente viene illustrato come eseguire l'override del comportamento di denominazione predefinito dei contratti dati e dei membri dati.
// This overrides the standard namespace mapping for all contracts
// in Contoso.CRM.
[assembly: ContractNamespace("http://schemas.example.com/crm",
ClrNamespace = "Contoso.CRM")]
namespace Contoso.CRM
{
// The namespace is overridden to become:
// http://schemas.example.com/crm.
// But the name is the default "Customer".
[DataContract]
public class Customer
{
// Code not shown.
}
}
namespace Contoso.OrderProc
{
[DataContract]
public class PurchaseOrder
{
// This data member is named "Amount" by default.
[DataMember]
public double Amount;
// The default is overridden to become "Address".
[DataMember(Name = "Address")]
public string Ship_to;
}
// The namespace is the default value:
// http://schemas.datacontract.org/2004/07/Contoso.OrderProc
// The name is "PurchaseOrder" instead of "MyInvoice".
[DataContract(Name = "PurchaseOrder")]
public class MyInvoice
{
// Code not shown.
}
// The contract name is "Payment" instead of "MyPayment"
// and the Namespace is "http://schemas.example.com" instead
// of the default.
[DataContract(Name = "Payment",
Namespace = "http://schemas.example.com")]
public class MyPayment
{
// Code not shown.
}
}
' This overrides the standard namespace mapping for all contracts
' in Contoso.CRM.
<Assembly: ContractNamespace("http://schemas.example.com/crm", _
ClrNamespace:="Contoso.CRM")>
Namespace Contoso.CRM
' The namespace is overridden to become:
' http://schemas.example.com/crm.
' But the name is the default "Customer".
<DataContract()> _
Public Class Customer
' Code not shown.
End Class
End Namespace
Namespace Contoso.OrderProc
<DataContract()> _
Public Class PurchaseOrder
' This data member is named "Amount" by default.
<DataMember()> _
Public Amount As Double
' The default is overridden to become "Address".
<DataMember(Name:="Address")> _
Public Ship_to As String
End Class
' The namespace is the default value:
' http://schemas.datacontract.org/2004/07/Contoso.OrderProc
' The name is "PurchaseOrder" instead of "MyInvoice".
<DataContract(Name:="PurchaseOrder")> _
Public Class MyInvoice
' Code not shown.
End Class
' The contract name is "Payment" instead of "MyPayment"
' and the Namespace is "http://schemas.example.com" instead
' of the default.
<DataContract(Name:="Payment", [Namespace]:="http://schemas.example.com")> _
Public Class MyPayment
' Code not shown.
End Class
End Namespace
Nomi dei contratti dati per i tipi generici
Esistono regole speciali per determinare i nomi dei contratti dati per i tipi generici. Queste regole aiutano a evitare conflitti di nome del contratto di dati tra due generici chiusi dello stesso tipo generico.
Per impostazione predefinita, il nome del contratto dati per un tipo generico è il nome del tipo, seguito dalla stringa "Of", seguito dai nomi dei contratti dati dei parametri generici, seguito da un hash calcolato usando gli spazi dei nomi del contratto dati dei parametri generici. Un hash è il risultato di una funzione matematica che funge da "impronta digitale" che identifica in modo univoco una parte di dati. Quando tutti i parametri generici sono tipi primitivi, l'hash viene omesso.
Ad esempio, vedere i tipi nell'esempio seguente.
[DataContract]
public class Drawing<Shape, Brush>
{
// Code not shown.
}
[DataContract(Namespace = "urn:shapes")]
public class Square
{
// Code not shown.
}
[DataContract(Name = "RedBrush", Namespace = "urn:default")]
public class RegularRedBrush
{
// Code not shown.
}
[DataContract(Name = "RedBrush", Namespace = "urn:special")]
public class SpecialRedBrush
{
// Code not shown.
}
<DataContract()> _
Public Class Drawing(Of Shape, Brush)
<DataContract([Namespace]:="urn:shapes")> _
Public Class Square
' Code not shown.
End Class
<DataContract(Name:="RedBrush", [Namespace]:="urn:default")> _
Public Class RegularRedBrush
' Code not shown.
End Class
<DataContract(Name:="RedBrush", [Namespace]:="urn:special")> _
Public Class SpecialRedBrush
' Code not shown.
End Class
End Class
In questo esempio, il tipo Drawing<Square,RegularRedBrush> ha il nome del contratto dati "DrawingOfSquareRedBrush5HWGAU6h", dove "5HWGAU6h" è un hash degli spazi dei nomi "urn:shapes" e "urn:default". Il tipo Drawing<Square,SpecialRedBrush> ha il nome del contratto di dati "DrawingOfSquareRedBrushjpB5LgQ_S", dove "jpB5LgQ_S" è un hash degli spazi dei nomi di "urn:shapes" e "urn:special". Si noti che se l'hash non viene usato, i due nomi sono identici e quindi si verifica un conflitto di nomi.
Personalizzazione dei nomi dei contratti dati per i tipi generici
In alcuni casi, i nomi dei contratti dati generati per i tipi generici, come descritto in precedenza, non sono accettabili. Ad esempio, è possibile sapere in anticipo che non si verificheranno conflitti di nome e potrebbe essere necessario rimuovere l'hash. In questo caso, è possibile usare la DataContractAttribute.Name proprietà per specificare un modo diverso per generare i nomi. È possibile usare i numeri tra parentesi graffe all'interno della proprietà Name per fare riferimento ai nomi dei contratti di dati dei parametri generici. 0 fa riferimento al primo parametro, 1 fa riferimento al secondo e così via. È possibile usare un segno numerico (#) all'interno di parentesi graffe per fare riferimento all'hash. È possibile usare ognuno di questi riferimenti più volte o non affatto.
Ad esempio, il tipo generico Drawing precedente potrebbe essere stato dichiarato come illustrato nell'esempio seguente.
[DataContract(Name = "Drawing_using_{1}_brush_and_{0}_shape")]
public class Drawing<Shape, Brush>
{
// Code not shown.
}
<DataContract(Name:="Drawing_using_{1}_brush_and_{0}_shape")> _
Public Class Drawing(Of Shape, Brush)
' Code not shown.
End Class
In questo caso, il tipo Drawing<Square,RegularRedBrush> ha come nome del contratto dati "Drawing_using_RedBrush_brush_and_Square_shape". Si noti che poiché nella proprietà è presente un oggetto "{#}", Name l'hash non fa parte del nome e pertanto il tipo è soggetto a conflitti di denominazione, ad esempio il tipo Drawing<Square,SpecialRedBrush> avrà esattamente lo stesso nome del contratto dati.