La WCF: DataMember l'attribut de la propriété vs membre
Dans wcf, quelle est la différence entre l'application de la DataMember
attribut sur une propriété
private int m_SomeValue;
[DataMember]
public int SomeValue {
get {...}
set {...}
}
au lieu d'une variable membre
[DataMember]
private int m_SomeValue;
public int SomeValue {
get {...}
set {...}
}
?
- vous n'avez pas besoin de faire une variable privée d'un membre de données.
Vous devez vous connecter pour publier un commentaire.
En général, vous devriez favoriser l'application de la DataMember l'attribut de la propriété, plutôt que sur le domaine privé. La seule raison pour appliquer l'attribut dans le champ de la place, c'est si le bien était en lecture seule (c'est à dire qu'il n'a pas de setter).
Aussi longtemps que vous utilisez le
Name
marqueur, le contrat est identique indépendamment de si le champ ou une propriété est utilisée.Cependant, il peut y avoir quelques problèmes d'autorisations d'accéder aux membres privés, en particulier sur silverlight et CF - dans ce cas, je vous conseille d'utiliser la propriété publique que les données membres. En fait, j'aurais tendance à toujours utiliser une propriété à moins que j'ai eu une très bonne raison...
Il y a de bonnes raisons que vous pouvez pour marquer les champs plutôt que de propriétés DataMember .
Veuillez vérifier ce pour plus de détails : http://blog.walteralmeida.com/2010/05/wcf-and-datacontract-serialization-internals-and-tips-.html
Par la route: ContractSerializers va sérialiser un domaine privé qui a le DataMemberAttribute sur elle seulement si en cours d'exécution dans la confiance totale de l'environnement. Ne fonctionne pas en confiance partielle (consultez le blog énumérés ci-dessus pour une solution)
Cette decission dépend de l'usage de vous service WCF:
Cas 1.
De sérialisation - est le processus de la persistance de l'état de l'objet. L'état de l'objet en C# est représenté par les champs de données.
Propriétés en C# sont essentiellement des méthodes, qui manipulent l'état de l'objet. Leur utilisation peut entraîner différents état de l'objet après la désérialisation, car l'ordre dans lequel les propriétés sont définies peuvent avoir un impact sur l'état des données. D'autres facteurs peuvent entraîner un état incorrect de la désérialisation trop, si par exemple la méthode (bien réglé) s'appuie sur le contexte qui est en train de changer, comme actuelles DateTime.
Vous pouvez dire ce à propos de l'encapsulation? Je ne veux pas que mon objet pour être en état non valide, et je dois faire des contrôles de validation, le graphe d'objet des vérifications d'intégrité, etc. Oui, vous devez, nous avons donc mis le DataMember attribs sur les accessoires? Pas de.
Le problème ici est que beaucoup de personnes de mélanger deux choses différentes, DTO (Data Transfer Object, WCF Contrat) avec le Domaine de l'Entité. Ce que vous avez besoin est de s'assurer que les données que vous recevez est exectly les mêmes données qui ont été envoyer, puis assurez-vous que vous pouvez construire valide Entité de Domaine à partir de ces données. La meilleure façon d'y parvenir est d'utiliser des classes séparées pour les DTO, et construire Entité de Domaine à partir d'eux.
Mais la plupart des programmeurs sont paresseux, et ils aiment à simple décorer Entité de Domaine avec DataMemeber attributs. Dans ce cas, la décision de Terrain ou des accessoires dépend de l'endroit où votre logique de validation est, si votre logique de validation est enterré dans l'Ensemble des méthodes, vous aurez à utiliser des Accessoires, si c'est extenral vous devez utiliser des Champs et de valider votre Domaine Entité après desirialization.
P. S. je pense que les mêmes règles s'appliquent à tout processus de sérialisation, comme les données de la base de persistnce.
Aussi, je tiens à mentionner que Silverlight ne peut pas sérialiser\désérialiser des champs privés, parce que vous ne pouvez pas y accéder de l'extérieur à l'aide de la réflexion, et vous aurez à les rendre privés et l'utilisation InternalsVisibleToAttribute.
Cas 2.
C'est dur. L'objectif principal ici est l'interopérabilité. Dans 99,9%, vous aurez séparé DTO classes dans ce cas, et probablement beaucoup de versions différentes de la leur à l'appui d'anciens clients. Il n'importe pas où vous mettez DataMembers attribs dans le présent, parce que vous utilisez la DTO de l'. Je ne vais pas la peine d'expliquer ce scénario, parce que les développeurs qui travaillent sur un tel système à grande échelle sont généralement assez connu, et ils ne sont pas la peine de lire DONC.
BinaryFormatter
etc ici. Cependant, en termes de interopérables morceau de données, lorsque la réception est de type pas identiques (il pourrait être mex/wsdl généré, ou pourrait être une plate-forme complètement différente), nous devrions avoir aucune connaissance (ou dépendance) les champs. Oui validation reste important, et il existe des mécanismes pour que (et d'autres choses, telles que des rappels).m_someValue
- le données estSomeValue
.m_someValue
est un détail d'implémentation. Il y a des façons de gérer la cartographie (comme : à l'aide deName
sur le terrain afin de fairem_someValue
apparaissent commeSomeValue
)En théorie, et aussi longtemps que vous le garder
m_SomeValue
toujours égale àSomeValue
(comme un simple getter/setter), rien. Autre que le nom de la variable exposés par la WCF. (Évidemment, si vous balisez lem_
variable, alors votre classe proxy sera également le mêmem_
nom. La classe proxy va générer une propriété publique si vous utilisez un public/protected/interne/domaine privé ou des biens.Toutefois, si vous avez toute une logique spéciale dans votre accesseurs qui peuvent modifier la valeur retournée (
ToUpper()
ing une chaîne de caractères, par exemple), alors vous renvoyer une valeur différente.Personnellement, je voudrais juste utiliser la propriété et complètement supprimé la variable de membre de l'ensemble. c'est à dire
La propriété inexplicablement créer une variable de membre de derrière les coulisses.
Si ajouter [DataMember] sur private int m_SomeValue, ce membre ne peut pas être la sérialisation,ce doit être l'ajouter sur public int SomeValue.
le code ci-dessus peut ne pas être d'obtenir la valeur du client si vous l'utilisez via WCF.