2012-12-20 3 views
7

Wir verwenden eine Basisklasse für alle Antwort-DTOs in unserer Anwendung. Die Klasse hat die folgende Signatur:WCF Abstrakte Basisklasse mit komplexer Sammlung von abstrakten Typen, die für die Deserialisierung in Serviceantwort nicht enthalten sind

[Serializable] 
public abstract class ResponseBase 
{ 
    public bool Successful { get; set; } 
    public List<ResponseMessage> Messages { get; set; } 

    //...Other code... 
} 

Die Nachrichten Sammlung eine der folgenden Typen:

[Serializable] 
[XmlInclude(typeof(DebugMessage))] 
[XmlInclude(typeof(InfoMessage))] 
[XmlInclude(typeof(ValidationMessage))] 
[XmlInclude(typeof(WarnMessage))] 
[XmlInclude(typeof(RecoverableFaultMessage))] 
[XmlInclude(typeof(FatalFaultMessage))] 
public abstract class ResponseMessage 
{ 
    //..Other code... 
} 

Mit konkreten Versionen:

[Serializable] 
public class DebugMessage : ResponseMessage 
{ 
    public override MessageType MessageType { get { return MessageType.Debug; } } 
} 
[Serializable] 
public class InfoMessage : ResponseMessage 
{ 
    public override MessageType MessageType { get { return MessageType.Info; } } 
} 
[Serializable] 
public class ValidationMessage : ResponseMessage 
{ 
    public override MessageType MessageType { get { return MessageType.Validation; } } 
} 
[Serializable] 
public class WarnMessage : ResponseMessage 
{ 
    public override MessageType MessageType { get { return MessageType.Warn; } } 
} 
[Serializable] 
public class RecoverableFaultMessage : ResponseMessage 
{ 
    public override MessageType MessageType { get { return MessageType.RecoverableFault; } } 
} 
[Serializable] 
public class FatalFaultMessage : ResponseMessage 
{ 
    public override MessageType MessageType { get { return MessageType.FatalFault; } } 
} 

Alle DTO Response-Objekte erben von ResponseBase jedoch auch mit folgenden ServiceKnownTypes auf dem WCF-Vertrag

[ServiceKnownType(typeof(ResponseBase))] 
[ServiceKnownType(typeof(ResponseMessage))] 
[ServiceKnownType(typeof(List<ResponseMessage>))] 
[ServiceKnownType(typeof(DebugMessage))] 
[ServiceKnownType(typeof(InfoMessage))] 
[ServiceKnownType(typeof(ValidationMessage))] 
[ServiceKnownType(typeof(WarnMessage))] 
[ServiceKnownType(typeof(RecoverableFaultMessage))] 
[ServiceKnownType(typeof(FatalFaultMessage))] 
[ServiceKnownType(typeof(List<DebugMessage>))] 
[ServiceKnownType(typeof(List<InfoMessage>))] 
[ServiceKnownType(typeof(List<ValidationMessage>))] 
[ServiceKnownType(typeof(List<WarnMessage>))] 
[ServiceKnownType(typeof(List<RecoverableFaultMessage>))] 
[ServiceKnownType(typeof(List<FatalFaultMessage>))] 

Wenn wir eine Nachricht in die ResponseBase Nachrichten Sammlung laden die folgende Ausnahme ausgelöst wird:

Fehler in Zeile 1 Position 906. Element ‚http://schemas.datacontract.org/2004/07/ CX.Framework.Common.BaseTypes: ResponseMessage ' enthält Daten von einem Typ, der dem Namen ' http://schemas.datacontract.org/2004/07/CX.Framework.Common.BaseTypes:WarnMessage 'zugeordnet ist. Der Deserializer hat keine Kenntnis von einem Typ, der diesem Namen zugeordnet ist. Erwägen Sie die Verwendung eines DataContractResolvers oder fügen Sie den Typ 'WarnMessage' zur Liste der bekannten Typen hinzu, z. B. indem Sie das KnownTypeAttribute-Attribut verwenden oder es zur Liste der bekannten an DataContractSerializer übergebenen Typen hinzufügen.

Wir haben alles von ServiceKnownType zu XMLInclude auf den abgeleiteten Typen getan. Ich bin ein wenig verloren, wie dies zu lösen ist und würde jede Hilfe schätzen, die jemand zur Verfügung stellen kann.

+2

Versuchen Sie, die bekannten Typattribute für die ResponseMessage in die ResponseBase-Klassendefinition zu übernehmen. Ich mache das ähnlich (mit '[DataContract]' und '[KnownType]') und es erfordert, dass die Klasse, die Mitglieder des polymorpher Typs hat, mit '[KnownType (typeof (DerivedTypeA))] 'dekoriert wird. –

+0

Sollte als Antwort @flem gepostet haben! Dies ist, was funktioniert hat und war die erste Antwort auf die Frage, stoßen Sie auf den Kommentar, aber danke für die Antwort. – VulgarBinary

+0

Vergnügen ... Es geht nicht nur um die Wiederholung! ;) –

Antwort

5

Ein paar Dinge:

1) [XmlInclude] wird keine Auswirkungen auf die DataContractSerializer haben, ist es nur durch die XmlSerializer verwendet.

2) Wie der Kommentator "Flem" vorgeschlagen, würde ich [KnownType] direkt auf ResponseMessage statt [ServiceKnownType] auf den Dienst verwenden.

3) Ich kann mich nicht erinnern, ob die DataContractSerializer sogar nach [KnownType] auf [Serializable] Typen sucht. Versuchen Sie zumindest für Testzwecke vorerst, Ihre Typen [DataContract] stattdessen (und die Datenmitglieder mit [DataMember]), wenn # 2 oben nicht hilft.

+1

# 2 hat gearbeitet, # 3 nicht. Da meine Bearbeitung nicht genehmigt wurde, werde ich sie hier einfügen, da anscheinend jeder, der es nicht genehmigt hat, nicht möchte, dass die Arbeitslösung für Passanten schnell und einfach zu bestimmen ist. – VulgarBinary

Verwandte Themen