2011-04-21 10 views
6

recientemente he notado en uno de los artículos de la operación del servicio WCF devuelve un collectiondatacontractWCF CollectionDataContract

Users GetUsers(string someInput); 

y usuarios tipo se define de la siguiente manera:

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

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

¿Tiene el retorno de una collectiondatacontract (como Usuarios en el este caso) tienen un propósito diferente a simplemente devolver List<User>?

+0

interesante .... – Seva

+1

¡Gracias! Lo usé, pero también necesitaba llamar al constructor base para hacer que funcione la generación de la página de Ayuda, así que en su ejemplo reemplace: 'public Users() {}' con 'public Users(): base() {}'. –

+0

@IanGrainger Algo más debe haber estado mal: el constructor base no arg se llama automáticamente si no se especifica lo contrario. – user2864740

Respuesta

4

Por lo que entiendo, este atributo le dará cierto control sobre qué nombres tendrán los elementos en la cadena final de xml, después de que DataContractSerializer haya hecho su trabajo de serialización de su colección.

Esto puede ser útil cuando tiene que analizar posteriormente el resultado (en otras palabras, sabrá qué elemento buscar en ese texto xml, para encontrar su colección y sus partes).

Tome un vistazo a esto para ejemplos y más información:

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

1

si devuelve una lista, el serializador de datos tiene una forma específica de generar xml. No sé cómo lo hace para List, pero si fuera una matriz, habría generado algo como - ... aquí Objeto de usuario 1 ... etc.

Pero utilizando CollectionDataContract puede serializarlo y exponerlo mejor para los consumidores que puedan crear XML a mano. Ejemplo - Yo sería capaz de dar - CollectionDataCOntract (name = "AllUsers") // no recuerdo NombreDeElemento o Nombre

entonces el XML esperado sería algo similar a - ... aquí objeto Usuario 1 ... etc.

Esa es una utilidad para esto.

0

Sólo para exponer sobre la respuesta de Andrei y compartir mi experiencia, acabo de ir a través de un tema que, finalmente, decidí usar CollectionDataContract. Básicamente, con el fin de interactuar con un sistema específico, que quería ser capaz de enviar y recibir XML del formato:

<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> 

Sin embargo, si utiliza una matriz o un objeto de lista, la etiqueta raíz se llamó siempre ArrayOfMessage. Y si crease una clase que tuviera una matriz de objetos Message (digamos llamada MsgList), WCF agregaría eso como una etiqueta extra en la mezcla, de la cual no podría encontrar una forma de deshacerme. Por lo que habría parecido:

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

Así CollectionDataContract sólo me dio una forma sencilla de controlar el nombre del elemento de la lista raíz.