locked
Verwendung von generischen Listen in WCF-Contract RRS feed

  • Frage

  • Hallo zusammen,

    Ist es möglich, von einem Service eine typensichere Liste unter Angabe des Types zurückzugeben?

    Folgendes probiere ich:

    [OperationContract]
    List<T> GetEntities<T>() where T : EntityType;

    Ziel ist dann ein Aufruf in der Form:
    List<EntityType_B> l = channel.GetEntities<EntityType_B>()

    Wenn ich den Contract so formuliere bekomme ich bereits beim Erzeugten des Channels die Ausnahme
    "Type 'System.Collections.Generic.List`1[T]' cannot be exported as a schema type because it is an open generic type.
    You can only export a generic type if all its generic parameter types are actual types."

    Ist das was ich versuche über WCF überhaupt möglich?

    Was klappt ist folgendes:

    [OperationContract]
    List<EntityType> GetEntities(string entityTypeName)

    und anschließend im die Einträge der Ergebnisliste in eine vom Zieltyp kopieren:

    List < EntityType > tmp = channel.GetEntities(typeof(T).FullName);
    List < T > list = new List<T>();
    foreach(EntityType e in tmp)
    {
     list.Add(e as T);  
    }

    Diese zusätzliche Kopieren würd ich mir gern sparen.

    Danke für Anregungen
    Torsten

    p.s.: 

    DataContract für Beispiel
    -------------------------

    [DataContract]
    [KnownType(typeof(EntityType_A))]
    [KnownType(typeof(EntityType_B))]
    public class EntityType
    { ...}

    [DataContract]
    [KnownType(typeof(EntityType_A_1))]
    public class EntityType_A : EntityType
    { ... }

    [DataContract]
    public class EntityType_B : EntityType
    { ... }

    [DataContract]
    public class EntityType_A_1 : EntityType_A
    { ... }

     

    Montag, 2. August 2010 12:19

Antworten

  • Hallo Frank,

    Hab jetzt folgenden Datenvertrag:

    [CollectionDataContract(Name="Entity{0}List", ItemName="EntityItem")]
    public class EntityList<T> : List<T>
    {
     public EntityList() : base() { } </form> 
      public EntityList(T[] items) {
      foreach (T item in items) { 
       Add(item);
      } 
     }
    }

    Mein Operation Contract wie folgt geändert:

    [OperationContract]
    EntityList<T> GetEntities<T>() where T : EntityType;

    Bekomme aber immer noch die gleich Ausnahme.

    Die Recherchen der letzten Stunden führen mich immer mehr zu der Vermutung, dass ein OperationContract mit der Rückgabe List<T> nicht möglich ist. Es läuft dann als Lösung immer auf List<MyType> als Rückgabewert hinaus.

    Ich werd wohl doch explizite Deklarationen verwenden

     

    List<EntityType_A> GetEntitiesA()
    List<EntityType_B> GetEntitiesB()
    List<EntityType_C> GetEntitiesC()


    usw.

    ciao
    Torsten

     

    Dienstag, 3. August 2010 08:37

Alle Antworten

  • Hallo Torsten,

    sollte mit dem CollectionDataContract-Attribut möglich sein:

    [CollectionDataContractAttribute-Klasse (System.Runtime.Serialization)]
    http://msdn.microsoft.com/de-de/library/system.runtime.serialization.collectiondatacontractattribute.aspx

    [Sammlungstypen in Datenverträgen]
    http://msdn.microsoft.com/de-de/library/aa347850.aspx

     


    ciao Frank
    Montag, 2. August 2010 15:20
  • Hallo Frank,

    Hab jetzt folgenden Datenvertrag:

    [CollectionDataContract(Name="Entity{0}List", ItemName="EntityItem")]
    public class EntityList<T> : List<T>
    {
     public EntityList() : base() { } </form> 
      public EntityList(T[] items) {
      foreach (T item in items) { 
       Add(item);
      } 
     }
    }

    Mein Operation Contract wie folgt geändert:

    [OperationContract]
    EntityList<T> GetEntities<T>() where T : EntityType;

    Bekomme aber immer noch die gleich Ausnahme.

    Die Recherchen der letzten Stunden führen mich immer mehr zu der Vermutung, dass ein OperationContract mit der Rückgabe List<T> nicht möglich ist. Es läuft dann als Lösung immer auf List<MyType> als Rückgabewert hinaus.

    Ich werd wohl doch explizite Deklarationen verwenden

     

    List<EntityType_A> GetEntitiesA()
    List<EntityType_B> GetEntitiesB()
    List<EntityType_C> GetEntitiesC()


    usw.

    ciao
    Torsten

     

    Dienstag, 3. August 2010 08:37