Das SetupWie eine Sammlung von einem Basistyp in WCF akzeptieren
Ich habe einen WCF-Dienst, der einen Basis-Typen macht (zB Tier) sowie einige abgeleitete Typen (zB Löwen, Tiger, und Bär). Ein anderer Typ (z. B. Zoo) enthält eine Eigenschaft, die eine Sammlung des Basistyps ist. Der Basistyp ist Beton, nicht abstrakt, so dass es vollkommen akzeptabel ist, dass die Sammlung Instanzen des Basistyps und/oder der abgeleiteten Typen (in beliebiger Kombination) enthält. Zum Beispiel:
[DataContract, KnownType(typeof(Lion)),
KnownType(typeof(Tiger)), KnownType(typeof(Bear))]
public class Animal
{
[DataMember]
public string Species { get; set; }
}
[DataContract]
public class Lion : Animal { }
[DataContract]
public class Tiger : Animal { }
[DataContract]
public class Bear : Animal { }
[DataContract]
public class Zoo
{
[DataMember]
public List<Animal> Animals { get; set; }
}
Einer meiner Service-Operationen übernimmt diese Art als Parameter, etwa so:
[ServiceContract]
public interface IZooService
{
[OperationContract]
void SetZoo(Zoo zoo);
}
All dies ist schön und gut, und das emittierte WSDL sieht für mich völlig in Ordnung. Sie enthält alle Typen und gibt korrekt an, dass die abgeleiteten Typen vom Basistyp erben. So soll ich in der Lage sein, meinen Dienst rufen eine SOAP-Nachricht mit, wie die folgenden:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:z="http://zoo.org">
<soapenv:Header/>
<soapenv:Body>
<z:SetZoo>
<z:Zoo>
<z:Animals>
<z:Animal>
<z:Species>Crocodile</z:Species>
</z:Animal>
<z:Tiger>
<z:Species>Bengal</z:Species>
</z:Tiger>
<z:Bear>
<z:Species>Grizzly</z:Species>
</z:Bear>
</z:Animals>
</z:Zoo>
</z:SetZoo>
</soapenv:Body>
</soapenv:Envelope>
In der obigen SOAP-Nachricht, die Tiere Sammlung enthält eine Instanz des Basistiertypen, eine Instanz der abgeleiteten Tiger type und eine Instanz des abgeleiteten Bear-Typs. WCF sollte diese Nachricht erfolgreich deserialisieren können.
Das Problem
WCF werfen keine Ausnahmen, wenn es die obige Meldung empfängt. Stattdessen werden die abgeleiteten Typen (Tiger und Bär) einfach ignoriert, und zu dem Zeitpunkt, an dem die deserialisierte Nachricht an meinen Code übergeben wird, enthält die Animals-Auflistung nur den Eintrag "Crocodile", da dieser vom Basistyp ist.
Also, ich denke, ich habe zwei Fragen ... Erstens, warum WCF die abgeleiteten Typ Instanzen in der Sammlung nicht deserialisiert. Und zweitens, weil WCF offensichtlich etwas an dieser SOAP-Nachricht nicht mag, warum gibt es keine Ausnahme? Diese Art des stillen Versagens ist sehr beunruhigend.
Ausgezeichnet, danke! Ich habe fast implodiert, eine richtige Nachricht mit Soap UI zu erstellen ... – juarola
Ich denke, der WCF-Deserializer ignoriert Teile der Nachricht ist mühsam. Dies würde Sie zwingen, immer den Client und den Server im Lockstep zu halten, nicht unbedingt ein wünschenswertes Merkmal. – Jeff