2010-01-15 13 views
6

verwendet wird Ich habe einen WCF-Dienst. Es verwendet Linq-to-Objekte, um aus einem Dictionary auszuwählen. Der Objekttyp ist einfach:Parameter des Typs 'System.Linq.Enumerable ...' kann nicht serialisiert werden, wenn WCF, LINQ, JSON

public class User 
{ 
    public Guid Id; 
    public String Name; 
} 

Es ist eine Sammlung von in einem Dictionary<Guid,User> gespeichert.

Ich möchte ein WCF OperationContract Methode wie diese haben:

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

Es fein kompiliert, aber wenn ich es benutze ich:

Der Server ist ein Fehler aufgetreten Verarbeiten der Anforderung. Die Ausnahmemeldung lautet 'Serialisierungsparameter vom Typ' System.Linq.Enumerable + WhereSelectEnumerableIterator 2[Cheeso.Samples.Webservices._2010.Jan.User,System.Guid]' (for operation 'GetAllUsers', contract 'IJsonService') because it is not the exact type 'System.Collections.Generic.IEnumerable 1 [System.Guid] 'in der Methodensignatur und ist nicht in der bekannten Typenauflistung. Um den Parameter zu serialisieren, fügen Sie den Typ der bekannten Typenauflistung für die Operation hinzu, die ServiceKnownTypeAttribute verwendet. Weitere Informationen finden Sie in den Serverprotokollen.

Wie kann ich die Auswahl zu einem IEnumerable<Guid> zwingen?


EDIT
Wenn ich den Code ändern, um dies zu tun, es funktioniert gut - gute Interoperabilität.

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

Gibt es eine Möglichkeit für mich, die Schaffung/Instanziierung des List<T> zu vermeiden?

Antwort

9

Nein, man muss eine konkrete Klasse von einem Webservice zurückgeben. Machen Sie den Rückgabetyp List und machen Sie damit fertig.

1

Sie müssen interoperable Sammlungen an und von Ihren WCF-Methoden übergeben.

WCF spielt am besten mit einfachen Typen und Arrays.

Übergeben Sie ein Array von Ihrem Client und machen Sie es dann zu einem IEnumerable im Service.

Zeug wie IEnumerable ist nicht interoperabel, was WCF versucht zu sein.

Es kann einen Weg geben, um es mit bekannten Typen zu umgehen, aber ich versuche immer, meine Komponenten so flexibel wie möglich zu machen.

+0

Ich denke, ich versuche nicht so sehr, ein IEnumerable zu verteilen. Was ich wirklich liefern möchte, ist eine Liste von Guids. aber ich wollte nicht unnötiges Casting machen müssen, um das zu ermöglichen. In der Tat kann ich nur den Rückgabetyp der Methode zu einer Liste ändern, und dann eine neue Liste erstellen die Auswahl in den List-Konstruktor übergeben - das funktioniert gut und der Client bekommt die Liste, wie ich will. Einfach genug. Ich hatte gehofft, dass die explizite Erstellung der Liste unnötig wäre. – Cheeso

+0

IEnumerable <> ist nur eine Schnittstelle, und es ist nicht ganz korrekt zu sagen, dass es nicht interoperabel ist, da dies vom initialisierten Typ abhängt, der IEnumerable <> implementiert, der von der Methode zurückgegeben wird. Ich habe IEnumerable <> als eine Rückkehr von Service-Operationen ohne Problem verwendet, aber der Schlüssel ist, dass der Rückgabewert der Operation ordnungsgemäß initialisiert werden muss. – Kwal

+0

MattK - Wie kann ich linq-to-objects verwenden, um eine Abfrage auszuführen, die zu einem IEnumerable führt, das ich von einer WCF-exposed-Methode zurückgeben kann? – Cheeso

4

Sie müssen das ServiceKnownTypes-Attribut verwenden.

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); 
    } 
} 

Grundsätzlich müssen Sie den konkreten Typ dessen, was Sie zurückgeben, wissen. Ziemlich einfach.

+0

+1 Für eine elegantere Lösung – Basic

Verwandte Themen