Quand utiliser les attributs DataContract et DataMember?

179

Je suis très confus au sujet de l' DataContractattribut dans WCF. Selon mes connaissances, il est utilisé pour sérialiser le type défini par l'utilisateur comme les classes. J'ai écrit une classe qui est exposée côté client comme ceci.

[DataContract]
public class Contact
{
    [DataMember]
    public int Roll { get; set; }

    [DataMember]
    public string Name { get; set; }

    [DataMember]
    public string Address { get; set; }

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

Cela fonctionne correctement, mais lorsque je le supprime DataContract, DataMembercela fonctionne également correctement. Je ne comprends pas pourquoi cela fonctionne correctement. Quelqu'un peut-il me dire à quoi sert réellement DataContract?

Mon contrat de service ressemble à ceci

[ServiceContract]    
public interface IRestServiceImpl
{
    [OperationContract]        
    Contact XmlData(string id);      
}
sam
la source
Une réponse parfaite est ici stackoverflow.com/questions/5681842/…
Asif Iqbal

Réponses:

361

Étant donné que de nombreux programmeurs étaient submergés par les attributs [DataContract]et [DataMember], avec .NET 3.5 SP1, Microsoft a fait en sorte que le sérialiseur de contrat de données gère toutes les classes - même sans aucun de ces attributs - un peu comme l'ancien sérialiseur XML.

Ainsi, à partir de .NET 3.5 SP1, vous n'avez plus à ajouter de contrat de données ou d'attributs de membre de données - si vous ne le faites pas, le sérialiseur de contrat de données sérialisera toutes les propriétés publiques de votre classe, tout comme le sérialiseur XML.

TOUTEFOIS: en n'ajoutant pas ces attributs, vous perdez beaucoup de fonctionnalités utiles:

  • sans [DataContract], vous ne pouvez pas définir un espace de noms XML pour vos données
  • sans [DataMember], vous ne pouvez pas sérialiser des propriétés ou des champs non publics
  • sans [DataMember], vous ne pouvez pas définir un ordre de sérialisation ( Order=) et le DCS sérialisera toutes les propriétés par ordre alphabétique
  • sans [DataMember], vous ne pouvez pas définir un nom différent pour votre propriété ( Name=)
  • sans [DataMember], vous ne pouvez pas définir des choses comme IsRequired=ou d'autres attributs utiles
  • sans [DataMember], vous ne pouvez pas omettre certaines propriétés publiques - toutes les propriétés publiques seront sérialisées par le DCS

Donc, pour une solution "quick'n'dirty", laisser de côté les attributs [DataContract]et [DataMember]fonctionnera - mais c'est toujours une bonne idée de les avoir sur vos classes de données - juste pour être plus explicite sur ce que vous faites et pour vous donner accès à toutes ces fonctionnalités supplémentaires que vous n'obtiendrez pas sans elles ...

marc_s
la source
vous voulez dire par défaut que tous les types de données sont marqués en interne comme sérialisables et nous avons utilisé DataContract / DataMember pour les restreindre.
santosh singh le
2
@Santosh: si vous avez une classe avec des propriétés publiques, celles-ci seront sérialisées par le sérialiseur de contrat de données WCF, sauf si vous appliquez explicitement [DataContract] / [DataMember] .- alors c'est à vous de dire à 100% ce qui est sérialisé et what not
marc_s
36
@Arthis: ce n'est pas tout à fait vrai. A partir de .NET 3.5 SP1, WCF heureusement des classes sérialisation sans aucune [DataContract] et [DataMember]attributs ... mais dès que vous commencez à utiliser l' un de ces attributs, ce comportement « par défaut » cessera de fonctionner - dès que vous avez un seul [DataMember] dans votre class, à partir de ce moment, seules les propriétés avec cet attribut seront sérialisées.
marc_s
4
Oohh! Merci d'avoir clarifié ce point! Je vais creuser un peu plus loin alors!
Arthis
6
Youhou! ça bascule !! Merci beaucoup!
Arthis
16

En termes de WCF, nous pouvons communiquer avec le serveur et le client via des messages. Pour transférer des messages, et à partir d'une perspective de sécurité, nous devons créer une donnée / un message dans un format sérialisé.

Pour la sérialisation des données, nous utilisons les attributs [datacontract] et [datamember]. Dans votre cas, si vous utilisez datacontractWCF utilise d' DataContractSerializerautres utilisations WCF XmlSerializerqui est la technique de sérialisation par défaut.

Laissez-moi vous expliquer en détail:

essentiellement WCF prend en charge 3 types de sérialisation:

  1. XmlSerializer
  2. DataContractSerializer
  3. NetDataContractSerializer

XmlSerializer : - L'ordre par défaut est identique à la classe

DataContractSerializer / NetDataContractSerializer : - L'ordre par défaut est alphabétique

XmlSerializer : - Le schéma XML est étendu

DataContractSerializer / NetDataContractSerializer : - Le schéma XML est contraint

XmlSerializer : - Prise en charge du contrôle de version impossible

DataContractSerializer / NetDataContractSerializer : - La prise en charge de la gestion des versions est possible

XmlSerializer : - Compatibilité avec ASMX

DataContractSerializer / NetDataContractSerializer : - Compatibilité avec .NET Remoting

XmlSerializer : - Attribut non requis dans XmlSerializer

DataContractSerializer / NetDataContractSerializer : - Attribut requis dans cette sérialisation

donc ce que vous utilisez dépend de vos besoins ...

Pradeep atkari
la source
8

Un contrat de données est un accord formel entre un service et un client qui décrit de manière abstraite les données à échanger. Autrement dit, pour communiquer, le client et le service n'ont pas à partager les mêmes types, mais uniquement les mêmes contrats de données. Un contrat de données définit précisément, pour chaque paramètre ou type de retour, quelles données sont sérialisées (transformées en XML) à échanger.

Windows Communication Foundation (WCF) utilise par défaut un moteur de sérialisation appelé Data Contract Serializer pour sérialiser et désérialiser les données (les convertir vers et à partir de XML). Tous les types primitifs .NET Framework, tels que les entiers et les chaînes, ainsi que certains types traités comme des primitives, tels que DateTime et XmlElement, peuvent être sérialisés sans autre préparation et sont considérés comme ayant des contrats de données par défaut. De nombreux types .NET Framework ont ​​également des contrats de données existants.

Vous pouvez trouver l'article complet ici.

mr.b
la source
2
C'est tout à fait vrai, mais cela ne répond pas vraiment à la question de l'OP de savoir pourquoi le sérialiseur de contrat de données fonctionne également sans aucun attribut [DataContract] et [DataMember] sur vos classes ...
marc_s
Quelqu'un peut-il me dire quelle est l'utilisation réelle de DataContract? - Je pense qu'au moins une partie de la question est répondue.
IAbstract
2

Un contrat de données est un accord formel entre un service et un client qui décrit de manière abstraite les données à échanger.

Le contrat de données peut être explicite ou implicite. Un type simple tel que int, string, etc. a un contrat de données implicite. Les objets définis par l'utilisateur sont de type explicite ou complexe, pour lesquels vous devez définir un contrat de données à l'aide de l'attribut [DataContract] et [DataMember].

Un contrat de données peut être défini comme suit:

  • Il décrit le format externe des données transmises vers et depuis les opérations de service

  • Il définit la structure et les types de données échangées dans les messages de service

  • Il mappe un type CLR à un schéma XML
  • Il définit comment les types de données sont sérialisés et désérialisés. Grâce à la sérialisation, vous convertissez un objet en une séquence d'octets pouvant être transmise sur un réseau. Grâce à la désérialisation, vous réassemblez un objet à partir d'une séquence d'octets que vous recevez d'une application appelante.
  • C'est un système de versionnage qui vous permet de gérer les modifications apportées aux données structurées

Nous devons inclure la référence System.Runtime.Serialization au projet. Cet assembly contient l'attribut DataContract et DataMember.

Kamran
la source
2
  1. Contrat de données: il spécifie que votre classe d'entité est prête pour le processus de sérialisation.

  2. Membres de données: il spécifie que le champ particulier fait partie du contrat de données et qu'il peut être sérialisé.

Mrunalini
la source
0

De plus, lorsque vous appelez à partir d'une requête http, cela fonctionnera correctement, mais lorsque vous essayez d'appeler à partir de net.tcp, vous obtenez toutes ces choses gentilles

Pramod
la source
0

L'attribut DataMember n'est pas obligatoire à ajouter pour sérialiser les données. Lorsque l'attribut DataMember n'est pas ajouté, l'ancien XMLSerializer sérialise les données. L'ajout d'un DataMember fournit des propriétés utiles comme l'ordre, le nom, est nécessaire qui ne peuvent pas être utilisées autrement.

Vijay Mishra
la source