2011-04-21 8 views
6

Niedawno zauważyliśmy w jednym z artykułów operacja usługa WCF zwrócił collectiondatacontractWCF CollectionDataContract

Users GetUsers(string someInput); 

a użytkownicy typu zostało zdefiniowane jak poniżej:

[CollectionDataContract] 
    public class Users : List<User> 
    { 
     public Users() 
     { 
     } 

     public Users(IEnumerable<User> users) : base(users) 
     { 
     } 
    } 

Czy przekazujących collectiondatacontract (jak użytkowników w w tym przypadku) służą innym celom, niż po prostu zwracaniu List<User>?

+0

ciekawe .... – Seva

+1

Dzięki! Używałem tego, ale musiałem również wywołać konstruktor bazowy, aby generowanie strony pomocy działało - więc w twoim przykładzie zamień: "public Users() {}" na "public Users(): base() {}". –

+0

@IanGrainger Coś jeszcze musiało być nie w porządku - konstruktor bazowy no-arg jest wywoływany automatycznie, jeśli nie podano inaczej. – user2864740

Odpowiedz

4

O ile rozumiem, ten atrybut da ci pewną kontrolę nad tym, jakie nazwy będą miały elementy w ostatecznym ciągu xml, po tym jak DataContractSerializer wykonał swoją pracę serializując kolekcję.

Może to być przydatne, gdy musisz później przeanalizować wynik ręcznie (innymi słowy, będziesz wiedział, jakiego elementu szukać w tym tekście xml, aby znaleźć swoją kolekcję i jej części).

Spójrz na to przykłady i więcej informacji:

http://msdn.microsoft.com/en-us/library/aa347850.aspx

1

jeśli zwrócisz listę, serializator danych ma określony sposób generowania xml. Nie wiem jak to robi dla List, ale jeśli byłaby to tablica, wygenerowałaby coś takiego - ... tutaj Obiekt użytkownika 1 ... itd.

Ale używając CollectionDataContract można serializować i lepiej eksponować dla konsumentów, którzy mogą tworzyć XML ręcznie. Przykład - byłbym w stanie dać - CollectionDataCOntract (name = "AllUsers") // dont pamiętać ItemName lub Nazwa

następnie XML spodziewać byłoby coś podobnego do - ... tutaj obiekt User 1 ... itd.

To jedno narzędzie do tego.

0

Wystarczy wyłożyć na odpowiedź Andrieja i podzielić się moim doświadczeniem, po prostu przeszedł problem, że w końcu rozwiązany za pomocą CollectionDataContract. Zasadniczo, w celu do współpracy z konkretnym systemem, chciałem, aby móc wysyłać i odbierać XML w formacie:

<SomeMessageList> 
    <Message> 
    <ID>blah</ID> 
    <data1>blah</data1> 
    <data2>etc.etc.</data2> 
    </Message> 
    <Message> 
    <ID>blah</ID> 
    <data1>blah</data1> 
    <data2>etc.etc.</data2> 
    </Message> 
    //any number of repeated <Message> here 
</SomeMessageList> 

Jednakże, jeśli użyłem tablicę lub obiekt listy, znacznik korzeń był zawsze nazywany ArrayOfMessage. I jeśli utworzyłem klasę, która zawierała tablicę obiektów Message (powiedzmy MsgList), to WCF dodałaby to jako dodatkowy tag w miksie, którego nie mogłem znaleźć sposobu na pozbycie się. Więc byłoby to wyglądało:

<SomeMessageList> 
    <MsgList> 
    <Message> 
     <ID>blah</ID> 
     <data1>blah</data1> 
     <data2>etc.etc.</data2> 
    </Message> 
    //any number of repeated <Message> here 
    </MsgList> 
</SomeMessageList> 

tak CollectionDataContract prostu dał mi prosty sposób kontrolować nazwę elementu listy korzeni.