7
votes

Ne peut pas sérialiser le paramètre de type 'system.linq.enumerable ...' lors de l'utilisation de wcf, linq, json

J'ai un service WCF. Il utilise LINQ-TO-Objets pour sélectionner un dictionnaire. Le type d'objet est simple: xxx pré>

Il existe une collection de ces stockées dans un dictionnaire code>. P>

Je veux avoir une méthode de fonctionnement code> de WCF de code> comme ceci: p> xxx pré>

Il compile bien, mais quand je l'exécute, je reçois: P>

Le serveur a rencontré une erreur de traitement de la demande. Le message d'exception est «ne peut pas sérialiser le paramètre de type 'System.Linq.enumerable + WheresElectEnpertoriatiterator (code> 2 [cheeso.samples.webservices._2010.jan.user, system.guid]' (pour l'opération 'getAlususers', contrat 'ijsonservice ') Parce que ce n'est pas le type exact' System.Collections.Generic.Inédiric.Inumerere code> 1 [System.Guid] 'Dans la signature méthode et n'est pas dans la collection de types connus. Afin de sérialiser le paramètre, ajoutez le type à la collection de types connus pour l'opération à l'aide de ServiceknownsknownTypeattribute. '. Voir les journaux du serveur pour plus de détails. P> blockQuote>

Comment puis-je contraindre la sélection à être un iEnumerable code>? p>


edit strong>
Si je modifie le code pour le faire, cela fonctionne bien - une bonne interopérabilité. P>

public List<Guid> GetAllUsers()
{
    var selection = from user in list.Values
        select user.Id;
     return new List<Guid>(selection);
}


0 commentaires

3 Réponses :


2
votes

Vous devez transmettre des collections interopérables vers et depuis vos méthodes WCF.

wcf joue le mieux avec des types simples et des tableaux.

transmettez-le dans un tableau de votre client, puis transformez-le en un iNeumable dans le service.

Des trucs comme iEnumérables n'est pas interopérable, ce qui est ce que WCF essaie d'être.

Il peut y avoir un moyen de se déplacer avec des types connus, mais je m'efforce toujours de rendre mes composants aussi flexibles que possible.


3 commentaires

Je suppose que je n'essaie pas tant de transmettre un iEnumerable. Ce que je veux vraiment délivrer, c'est une liste de Guids. Mais je ne voulais pas avoir à faire un casting inutile pour que cela se produise. En fait, je peux simplement modifier le type de retour de la méthode vers une liste , puis créer une nouvelle liste Passer la sélection dans le constructeur de liste - cela fonctionne simplement et le client obtient la liste de la manière dont je veux . Assez simple. J'espérais que la création explicite de la liste serait inutile.


IEnumerable <> est juste une interface et il n'est pas tout à fait correct de dire qu'il n'est pas interopérable car cela dépend du type initialisé qui implémente Ienumerable <> qui est renvoyé par la méthode. J'ai utilisé Ienumerable <> comme un retour des opérations de service sans aucun problème, mais la clé est que la valeur de retour de l'opération doit être initialisée correctement.


Mattk - Alors, comment puis-je utiliser Linq-A-Objects pour effectuer une requête qui donne un iNeumable que je peux revenir d'une méthode exposée par la WCF?



11
votes

Non, il faut renvoyer une classe concrète d'un service Web. Faites la liste des types de retour et faites-la avec elle.


0 commentaires

5
votes

Vous devez utiliser l'attribut ServiceknownTypes.

using System;
using System.Collections.Generic;
using System.ServiceModel;
using System.ServiceModel.Web;

namespace Test.Service
{
    [ServiceContract(Name = "Service", Namespace = "")]
    public interface IService
    {
        [OperationContract]
        [WebInvoke(
            Method = "GET",
            BodyStyle = WebMessageBodyStyle.WrappedRequest,
            RequestFormat = WebMessageFormat.Json,
            ResponseFormat = WebMessageFormat.Json)]
        [ServiceKnownType(typeof(List<EventData>))]
        IEnumerable<EventData> Method(Guid userId);
    }
}


0 commentaires