2010-01-20 13 views
3

possible duplicate:
Cannot serialize parameter of type ‘System.Linq.Enumerable… ’ when using WCF, LINQ, JSONdonnées Sérialisation à l'aide IEnumerable <T> avec WebGet


Salut,

Si ma méthode signiature ressemble à ceci, il fonctionne très bien.

[WebGet] 
MyClass[] WebMethod() 

Si le signiature ressemble à ceci

[WebGet] 
IEnumerable<T> WebMethod() 

Je reçois l'erreur suivante: Impossible de sérialiser paramètre de type 'XYZT + <WebMethod> d__2c' (pour le fonctionnement 'WebMethod', contrat « IService ') parce que ce n'est pas le type exact' System.Collections.Generic.IEnumerable`1 [XYZT] 'dans la signature de la méthode et n'est pas dans la collection des types connus. Pour sérialiser le paramètre, ajoutez le type à la collection de types connus pour l'opération à l'aide de ServiceKnownTypeAttribute.

J'ai essayé d'ajouter. ServiceKnownType (typeof (IEnumerable))

Même erreur.

S'agit-il d'un bogue dans la version bêta 2 de 2010, ou est-ce probablement le cas à l'avenir?

Merci

+0

duplication possible de http://stackoverflow.com/questions/2068897/cannot-serialize-parameter-of-type-system-linq-enumerable-when-using-wcf-l –

Répondre

7

Les types iterator générés par le compilateur C# ne sont pas sérialisables et ne le seront jamais.

Si vous lisez this page, vous verrez qu'il ne serait pas logique de sérialiser l'itérateur.

Vous devez retourner un tableau.

EDIT: La façon la plus simple de le faire est de déplacer votre itérateur à une méthode séparée, et changer WebMethod à

[WebGet] 
MyClass[] WebMethod() { return OtherMethod().ToArray(); } 
+1

Si nécessaire, vous pouvez certainement travailler avec 'IEnumerable ' à l'intérieur de la méthode ... puis utilisez la méthode 'IEnumerable .ToArray()' pour retourner la collection en tant que tableau. –

+0

Ou vous pouvez retourner une liste Cheeso

+0

Oui, mais pourquoi s'embêter? – SLaks

1

J'ai couru dans le même problème, et dans mon cas, il est tout simplement impossible de modifier mon graphe d'objet entier de IEnumerable à base d'itérateur à des types concrets. Je ne peux tout simplement pas me permettre de convertir la mémoire en types concrets comme List ou Array. De plus, qu'en est-il du cas où je retourne un IEnumerable d'un objet qui a une propriété IEnumerable. Il est inacceptable que je doive recurse mon graphe d'objet entier en convertissant tous les IEnumerables.

Je ne vois aucune bonne raison pour laquelle DataContractSerializer ne peut pas itérer tout type IEnumerable et rendre ses éléments au format XML de la même manière que tout autre type de collection, même si IEnumerable n'a pas de type de support concret .

Ceci est un bug qui devrait être corrigé.

+0

La façon dont WCF fonctionne par défaut consiste à utiliser la messagerie tamponnée, ce qui signifie que l'ensemble du graphe d'objet sérialisé de votre valeur de retour est intégré dans la mémoire avant d'être renvoyé au client. Pour cette raison, même si vous pouviez renvoyer un IEnumerable, cela n'aiderait pas la consommation de mémoire. Vous pouvez toutefois activer les transferts en streaming qui provoqueront l'envoi du message tel qu'il est sérialisé. Malheureusement, vous devez utiliser Stream, IXmlSerializable ou Message comme type de retour pour utiliser le streaming. IEnumerable n'est toujours pas autorisé. Voir http://msdn.microsoft.com/en-us/library/ms789010.aspx – luksan