2009-08-18 11 views
6

J'ai un objet qui a un IList générique ce qui est de retour d'une méthode de service Web WCF:WCF IList sérialisation Problème

[DataContract(Name = "PageableList_Of_{0}")] 
public class PageableResults<T> 
{ 
    [DataMember] 
    public IList<T> Items { get; set; } 
    [DataMember] 
    public int TotalRows { get; set; } 
} 

[OperationContract] 
PageableResults<ContentItem> ListCI(); 

Quand j'appelle cette méthode sur le service qu'elle exécute toute fin de la méthode , mais à la toute fin, il lance une exception System.ExecutionEngineException sans InnerException. J'ai essayé de renvoyer un objet concret de List <> et cela semble fonctionner, mais malheureusement je dois trouver une solution de contournement pour renvoyer un IList. Y a-t-il des attributs que je dois mettre en place pour résoudre ce problème?

+0

Vous dites "quand j'appelle cette méthode sur le service" - L'erreur est-elle réelle lors de la désérialisation du résultat? –

+0

Je pense que ça se passe du côté du service quand il s'agit de sérialiser l'objet puisqu'il se déclenche juste quand je quitte la méthode de service, mais il n'y a aucune trace de pile dans l'exception donc je ne peux pas être positif. – Nick

Répondre

1

Vous devez ajouter KnownTypes attribut sur la définition de classe au-dessus de votre définition de classe pour chaque utilisation de T. Comme ceci:


[KnownType(typeof(ContentItem))] 
[DataContract(Name = "PageableList_Of_{0}")] 
public class PageableResults<T> 
{ 
    [DataMember] 
    public IList<T> Items { get; set; } 
    [DataMember] 
    public int TotalRows { get; set; } 
} 

[OperationContract] 
PageableResults ListCI(); 

Vous pouvez également définir votre propre classe de collection, qui possède une propriété totalRows , comme ceci:


[KnownType(typeof(ContentItem))] 
[DataContract(Name = "PageableList_Of_{0}")] 
public class PageableResults<T> : EntityCollectionWorkaround<T> 
{ 
    [DataMember] 
    public int TotalRows { get; set; } 
} 

Où EntityCollectionWorkaround est défini ici:
http://borismod.blogspot.com/2009/06/v2-wcf-collectiondatacontract-and.html

1

Je ne pense pas que vous pouvez le faire. Comment le sérialiseur sait-il quoi désarticuler? Beaucoup de choses pourraient implémenter un IList, et une interface n'a pas de constructeur.

+0

Il semble fonctionner correctement lors de l'utilisation de netTcpBinding, mais pas avec WSHttpBinding – Nick

+0

quel est le type sous-jacent auquel il est désérialisé? Je ne vois pas comment cela pourrait fonctionner à moins de choisir au hasard un conteneur qui implémente IList et de le coller là-dedans. – Steve

0

Hériter de PageableResults pour créer une sous-classe générique fermée, dans votre cas PageableContentItem ou quelque chose comme ça, et l'utiliser comme type de retour. Avec les webservices, le sérialiseur xml est normalement utilisé et il doit tout savoir à l'avance, c'est pourquoi vous ne pouvez pas retourner les types d'interface.

public class PageableContentItem 
     : PageableResults<ContentItem> 
    { 

    } 

[OperationContract] 
PageableContentItem ListCI();