Kiedy używać atrybutów DataContract i DataMember?

179

Jestem bardzo zdezorientowany co do DataContractatrybutu w WCF. Zgodnie z moją wiedzą jest on używany do serializacji typu zdefiniowanego przez użytkownika, takiego jak klasy. Napisałem jedną klasę, która jest dostępna po stronie klienta w ten sposób.

[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; }
}

Działa poprawnie, ale kiedy go usunę DataContracti DataMemberdziała również poprawnie. Nie rozumiem, dlaczego działa poprawnie. Czy ktoś może mi powiedzieć, jakie jest rzeczywiste zastosowanie DataContract?

Moja umowa serwisowa wygląda następująco

[ServiceContract]    
public interface IRestServiceImpl
{
    [OperationContract]        
    Contact XmlData(string id);      
}
sam
źródło
Idealna odpowiedź znajduje się tutaj stackoverflow.com/questions/5681842/...
Asif Iqbal

Odpowiedzi:

361

Ponieważ wielu programistów zostało przytłoczonych atrybutami [DataContract]i [DataMember], w .NET 3.5 SP1 Microsoft spowodował, że serializator kontraktów danych obsługuje wszystkie klasy - nawet bez tych atrybutów - podobnie jak stary serializator XML.

Od wersji .NET 3.5 SP1 nie musisz już dodawać atrybutów danych ani atrybutów elementów danych - jeśli tego nie zrobisz, serializator kontraktu danych serializuje wszystkie właściwości publiczne w twojej klasie, podobnie jak serializator XML.

JEDNAK: nie dodając tych atrybutów, tracisz wiele przydatnych możliwości:

  • bez tego [DataContract]nie można zdefiniować przestrzeni nazw XML, w której będą przechowywane dane
  • bez tego [DataMember]nie można serializować niepublicznych właściwości ani pól
  • bez tego [DataMember]nie można zdefiniować kolejności serializacji ( Order=), a DCS serializuje wszystkie właściwości alfabetycznie
  • bez [DataMember]nie można zdefiniować innej nazwy dla swojej właściwości ( Name=)
  • bez tego [DataMember]nie można zdefiniować rzeczy takich jak IsRequired=lub innych przydatnych atrybutów
  • bez tego [DataMember]nie można pominąć niektórych właściwości publicznych - wszystkie właściwości publiczne zostaną zserializowane przez DCS

Tak więc w przypadku rozwiązania typu „szybkie i brudne” pozostawienie atrybutów [DataContract]i [DataMember]będzie działać - ale nadal dobrze jest mieć je w swoich klasach danych - aby być bardziej wyraźnym na temat tego, co robisz, i dać sobie dostęp do wszystkich tych dodatkowych funkcji, których nie uzyskasz bez nich ...

marc_s
źródło
masz na myśli domyślnie, że wszystkie typy danych są wewnętrznie oznaczone jako szeregowalne i użyliśmy DataContract / DataMember do ich ograniczenia.
santosh singh
2
@Santosh: jeśli masz klasę z niektórymi właściwościami publicznymi, zostaną one zserializowane przez Serializer danych kontraktu WCF, chyba że wyraźnie zastosujesz [DataContract] / [DataMember]. - to w 100% od Ciebie zależy, co zostanie serializowane i co nie
marc_s
36
@Arthis: to nie do końca prawda. Począwszy od .NET 3.5 SP1, WCF chętnie serializuje klasy bez żadnych atrybutów [DataContract]i [DataMember]atrybutów ... ale jak tylko zaczniesz używać jednego z tych atrybutów, wówczas to „domyślne” zachowanie przestanie działać - jak tylko będziesz mieć jeden [DataMember] w swoim klasa, od tego momentu tylko te właściwości z tym atrybutem będą serializowane.
marc_s
4
Och! Dziękujemy za wyjaśnienie tej kwestii! Wykopię to trochę dalej!
Arthis
6
Youhou! To rządzi!! Merci beaucoup!
Arthis
16

W zakresie WCF możemy komunikować się z serwerem i klientem za pomocą wiadomości. Do przesyłania wiadomości i ze względów bezpieczeństwa musimy utworzyć dane / wiadomości w formacie zserializowanym.

Do szeregowania danych używamy atrybutów [datacontract] i [datamember]. W twoim przypadku, jeśli używasz datacontractWCF, używa DataContractSerializerinnego WCF, XmlSerializerktóry jest domyślną techniką serializacji.

Pozwól mi wyjaśnić szczegółowo:

w zasadzie WCF obsługuje 3 typy serializacji:

  1. XmlSerializer
  2. DataContractSerializer
  3. NetDataContractSerializer

XmlSerializer : - Domyślna kolejność jest taka sama jak dla klasy

DataContractSerializer / NetDataContractSerializer : - Domyślna kolejność jest alfabetyczna

XmlSerializer : - Schemat XML jest obszerny

DataContractSerializer / NetDataContractSerializer : - Schemat XML jest ograniczony

XmlSerializer : - Obsługa wersji nie jest możliwa

DataContractSerializer / NetDataContractSerializer : - Obsługa wersji jest możliwa

XmlSerializer : - Kompatybilność z ASMX

DataContractSerializer / NetDataContractSerializer : - Kompatybilność z .NET Remoting

XmlSerializer : - Atrybut nie jest wymagany w XmlSerializer

DataContractSerializer / NetDataContractSerializer : - Atrybut wymagany w tej serializacji

więc to, czego używasz, zależy od twoich wymagań ...

Pradeep atkari
źródło
8

Umowa danych to formalna umowa między usługą a klientem, która w sposób abstrakcyjny opisuje dane, które mają być wymieniane. Oznacza to, że aby się komunikować, klient i usługa nie muszą dzielić tych samych typów, tylko te same umowy dotyczące danych. Kontrakt danych precyzyjnie określa, dla każdego parametru lub typu zwracanego, jakie dane są serializowane (zamieniane w XML) do wymiany.

Windows Communication Foundation (WCF) używa domyślnie silnika serializacji o nazwie Data Contract Serializer do serializacji i deserializacji danych (konwersja do i z XML). Wszystkie pierwotne typy .NET Framework, takie jak liczby całkowite i ciągi, a także niektóre typy traktowane jako operacje podstawowe, takie jak DateTime i XmlElement, mogą być serializowane bez żadnego innego przygotowania i są traktowane jako posiadające domyślne kontrakty danych. Wiele typów .NET Framework ma również istniejące kontrakty danych.

Pełny artykuł można znaleźć tutaj.

mr.b
źródło
2
To wszystko prawda i w porządku, ale tak naprawdę nie odpowiada na pytanie OP, dlaczego serializator kontraktu danych działa również bez atrybutów [DataContract] i [DataMember] na twoich klasach ...
marc_s
Czy ktoś może mi powiedzieć, jakie jest faktyczne wykorzystanie DataContract? - Myślę, że przynajmniej część pytania została udzielona.
IAbstract
2

Umowa danych to formalna umowa między usługą a klientem, która w sposób abstrakcyjny opisuje dane, które mają być wymieniane.

Umowa danych może być jawna lub dorozumiana. Typ prosty, taki jak int, string itp., Zawiera niejawny kontrakt danych. Obiekt zdefiniowany przez użytkownika jest jawny lub typu złożonego, dla którego musisz zdefiniować kontrakt danych za pomocą atrybutu [DataContract] i [DataMember].

Kontrakt danych można zdefiniować w następujący sposób:

  • Opisuje zewnętrzny format danych przekazywanych do iz operacji serwisowych

  • Definiuje strukturę i typy danych wymienianych w komunikatach serwisowych

  • Odwzorowuje typ CLR na schemat XML
  • Definiuje sposób serializacji i deserializacji typów danych. Poprzez serializację przekształcasz obiekt w sekwencję bajtów, które mogą być przesyłane przez sieć. Poprzez deserializację ponownie składasz obiekt z sekwencji bajtów otrzymanych z aplikacji wywołującej.
  • Jest to system kontroli wersji, który pozwala zarządzać zmianami danych strukturalnych

Musimy dołączyć odwołanie System.Runtime.Serialization do projektu. Ten zespół zawiera atrybuty DataContract i DataMember.

Kamran
źródło
2
  1. Kontrakt danych: określa, że ​​klasa encji jest gotowa do procesu serializacji.

  2. Członkowie danych: określa, że ​​dane pole jest częścią kontraktu danych i może być szeregowane.

Mrunalini
źródło
0

Również gdy zadzwonisz z żądania http, będzie działać poprawnie, ale kiedy spróbujesz zadzwonić z net.tcp, tym razem otrzymasz wszystkie tego rodzaju rzeczy

Pramod
źródło
0

Atrybut DataMember nie jest obowiązkowy, aby dodać dane do serializacji. Gdy atrybut DataMember nie zostanie dodany, stary XMLSerializer serializuje dane. Dodanie DataMember zapewnia użyteczne właściwości, takie jak kolejność, nazwa, wymagane, których nie można użyć inaczej.

Vijay Mishra
źródło