web-dev-qa-db-fra.com

Quel est l'intérêt d'un DataContract dans WCF?

VS.net crée un modèle lorsque vous créez un projet WCF.

Il ajoute une classe au fichier iService1.cs:

// Use a data contract as illustrated in the sample below to
// add composite types to service operations.
[DataContract]
public class CompositeType
{
    bool boolValue = true;
    string stringValue = "Hello ";

    [DataMember]
    public bool BoolValue
    {
        get { return boolValue; }
        set { boolValue = value; }
    }

    [DataMember]
    public string StringValue
    {
        get { return stringValue; }
        set { stringValue = value; }
    }
}

Puisqu'un service WCF peut renvoyer n'importe quelle classe définie par l'utilisateur, pourquoi utiliser une classe DataContract et CompositeType?

Je peux retourner quelque chose comme:

 [OperationContract]
MyUserCollection GetUsers();

Qu'est-ce que je rate?

50
Blankman

Le DataContract n'est qu'une définition formelle d'un type qui peut être compris des deux côtés de la frontière du service.

Si vous retournez, comme dans votre exemple, un objet "MyUserCollection", les consommateurs de votre service devront faire référence aux entrailles de votre service/système, ce qui constitue une violation du principe SOA limites explicites. En utilisant un DataContract, vous publiez la structure de vos types de retour de manière peu couplée.

52
Guy Starbuck

Une autre chose intéressante à noter est que si vous décorez votre code avec DataContract, vous avez beaucoup de contrôle sur ce que le client peut voir et que vous devez renvoyer à votre service. Par exemple:

[DataContract]
public class SampleClass
{
    [DataMember(IsRequired=true)]
    public int MyRequiredProperty { get; set; }

    [DataMember]
    public int MyOptionalProperty { get; set; }

    public int MyInternalProperty { get; set; }
}

Dans l'exemple ci-dessus, vous avez défini que lors de la réception de données, vous DEVEZ avoir MyRequiredProperty, et vous pouvez avoir ou non MyOptionalProperty. De plus, le client ne verra jamais MyInternalProperty (cela peut être par exemple une propriété qui aide votre logique en interne, mais vous ne voulez pas qu'elle soit exposée au niveau du client).

26
Wagner Silveira

Il y a une autre utilisation importante, vous pouvez changer le nom de la classe et des propriétés. C'est une fonctionnalité pratique lors de la sérialisation et de la désérialisation.

[DataContract(Name="EmployeeName")]
public class Person
{
   [DataMember(Name="FullName")]
   public string Name { get; set; }

   [DataMember(Name="HomeAddress")]
   public string Address { get; set; }
}
11
Asif Mushtaq

Je ne suis pas d'accord avec l'affiche qui a déclaré: "Le DataContract n'est qu'une définition formelle d'un type qui peut être compris des deux côtés de la frontière du service."

Le mot-clé ici est "type". Dans .NET, un type est un objet qui peut avoir des champs, des propriétés et des méthodes. Cependant, lorsque vous décorez une classe avec DataContract dans votre service WCF, le résultat n'est pas la classe étant transplantée comme par magie dans le code appelant; pas de loin! Dans le code appelant, vous aurez une classe "proxy". La classe proxy reçoit du XML qui représente le contenu du contrat de données. Le code appelant peut recevoir ces valeurs XML via la classe proxy, mais il pas donne au code appelant l'accès aux entrailles de la classe à décorer avec datacontract.

2

Pour répondre à "marc_s":

"Si vous avez .NET aux deux extrémités du câble, c'est très bien. Et si vous avez un client Java appelant votre service? Si vous placez vos données dans DataContracts, ces informations sont stockées dans les métadonnées WSDL/XSD et peuvent également être utilisées par des clients autres que .NET. "

Je pense que c'est faux. Essayons de faire ceci:

  1. Utilisez l'exemple par défaut du projet WCF avec une classe avec des attributs DataContract sur les classes et DataMember sur les membres, et une méthode qui renvoie ce type.
  2. Construisez-le et affichez le wsdl. Le xsd contient la définition CompositeType. D'ACCORD.
  3. Supprimons maintenant tous les attributs DataContract et DataMember
  4. Construisez-le et affichez le wsdl. Le xsd contient toujours la définition de ComposityType! (c'est plus évident avec un logiciel SCM, qui ne montre aucune différence de fichiers entre les étapes 2 et 4)

Donc, un client Java doit gérer cela, sans DataContract et DataMember! Ai-je tort ou quoi?

2
WolveFred

Peut-être pas souvent utilisé, nous pourrions utiliser [DataContract] pour passer à travers des variables privées. DataContractSerializer ne sérialise/désérialise que les types visibles publiquement si l'attribut [DataContract] n'est pas utilisé.

[DataContract]
public class SampleClass
{    
    [DataMember]
    private int MyPrivateProperty { get; set; }
}

(Remarque: si vous générez un proxy, les membres privés sont affichés comme publics)

0
thewpfguy