Partage via


Noms des contrats de données

Parfois, un client et un service ne partagent pas les mêmes types. Ils peuvent toujours transmettre des données les unes aux autres tant que les contrats de données sont équivalents des deux côtés. L’équivalence des contrats de données est basée sur les noms des contrats de données et des membres de données. Un mécanisme est donc fourni pour mapper des types et des membres à ces noms. Cette rubrique explique les règles de nommage des contrats de données ainsi que le comportement par défaut de l’infrastructure Windows Communication Foundation (WCF) lors de la création de noms.

Règles de base

Les règles de base relatives aux contrats de données d’affectation de noms sont les suivantes :

  • Un nom de contrat de données complet se compose d'un espace de noms et d'un nom.

  • Les membres de données incluent uniquement des noms, mais pas d'espace de noms.

  • Lors du traitement des contrats de données, l’infrastructure WCF respecte aussi bien la casse des espaces de noms que celle des noms de contrats de données et de membres de données.

Espaces de noms de contrat de données

Un espace de noms de contrat de données prend la forme d’un URI (Uniform Resource Identifier). L’URI peut être absolu ou relatif. Par défaut, les contrats de données pour un type particulier sont affectés à un espace de noms qui provient de l’espace de noms CLR (Common Language Runtime) de ce type.

Par défaut, tout espace de noms CLR donné (au format Clr.Namespace) est mappé à l’espace de noms http://schemas.datacontract.org/2004/07/Clr.Namespace. Pour remplacer cette valeur par défaut, appliquez l’attribut ContractNamespaceAttribute à l’ensemble du module ou de l’assembly. Vous pouvez également contrôler l'espace de noms du contrat de données pour chaque type en définissant la propriété Namespace de DataContractAttribute.

Remarque

L'espace de noms http://schemas.microsoft.com/2003/10/Serialization est réservé et ne peut pas être utilisé comme espace de noms de contrat de données.

Remarque

Vous ne pouvez pas remplacer l’espace de noms par défaut dans les types de contrats de données qui contiennent des delegate déclarations.

Noms des contrats de données

Le nom par défaut d’un contrat de données pour un type donné est le nom de ce type. Pour remplacer la valeur par défaut, définissez la propriété Name de DataContractAttribute à un nom alternatif. Les règles spéciales pour les types génériques sont décrites dans « Noms de contrat de données pour les types génériques » plus loin dans cette rubrique.

Noms de membre de données

Le nom par défaut d’un membre de données pour un champ ou une propriété donné est le nom de ce champ ou de cette propriété. Pour remplacer la valeur par défaut, attribuez à la propriété Name la valeur alternative DataMemberAttribute.

Exemples

L’exemple suivant montre comment remplacer le comportement d’affectation de noms par défaut des contrats de données et des membres de données.

// 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

Noms de contrat de données pour les types génériques

Des règles spéciales existent pour déterminer les noms de contrat de données pour les types génériques. Ces règles permettent d’éviter les collisions de noms de contrat de données entre deux génériques fermés du même type générique.

Par défaut, le nom du contrat de données pour un type générique est le nom du type, suivi de la chaîne « Of », suivi des noms de contrat de données des paramètres génériques, suivi d’un hachage calculé à l’aide des espaces de noms de contrat de données des paramètres génériques. Un hachage est le résultat d’une fonction mathématique qui agit comme une « empreinte digitale » qui identifie de manière unique un élément de données. Lorsque tous les paramètres génériques sont des types primitifs, le hachage est omis.

Par exemple, consultez les types de l’exemple suivant.

[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

Dans cet exemple, le type Drawing<Square,RegularRedBrush> a le nom de contrat de données "DrawingOfSquareRedBrush5HWGAU6h", où "5HWGAU6h" est un hachage des espaces de noms "urn:shapes" et "urn:default". Le type Drawing<Square,SpecialRedBrush> a le nom de contrat de données "DrawingOfSquareRedBrushjpB5LgQ_S", où "jpB5LgQ_S" est un hachage des espaces de noms "urn:shapes" et "urn:special". Notez que si le hachage n’est pas utilisé, les deux noms sont identiques et, par conséquent, une collision de noms se produit.

Personnalisation des noms de contrat de données pour les types génériques

Parfois, les noms de contrat de données générés pour les types génériques, comme décrit précédemment, sont inacceptables. Par exemple, peut-être savez-vous déjà qu'il n'y aura pas de conflit de noms et souhaitez supprimer le hachage. Dans ce cas, vous pouvez utiliser la DataContractAttribute.Name propriété pour spécifier une autre façon de générer des noms. Vous pouvez utiliser des nombres entre accolades dans la propriété Name pour référencer les noms de contrats de données des paramètres génériques. (0 fait référence au premier paramètre, 1 fait référence au deuxième, et ainsi de suite.) Vous pouvez utiliser un signe numérique (#) à l’intérieur des accolades pour faire référence au hachage. Vous pouvez utiliser chacune de ces références plusieurs fois ou pas du tout.

Par exemple, le type générique Drawing précédent peut avoir été déclaré comme indiqué dans l’exemple suivant.

[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

Dans ce cas, le type Drawing<Square,RegularRedBrush> a le nom de contrat de données "Drawing_using_RedBrush_brush_and_Square_shape". Notez que, étant donné qu’il existe un « {#} » dans la propriété Name, le hachage n’est pas une partie du nom, et donc le type est susceptible aux collisions de nommage ; par exemple, le type Drawing<Square,SpecialRedBrush> aurait exactement le même nom de contrat de données.

Voir aussi