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?
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.
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).
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; }
}
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
.
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:
Donc, un client Java doit gérer cela, sans DataContract et DataMember! Ai-je tort ou quoi?
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)