WCF An abstract base class with a complex set of abstract types not included for deserialization in a service response

We use the base class for all of our DTO responses in our application. The class has the following signature:

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

A collection of messages can be any of the following types:

 [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... } 

With specific versions:

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

All DTO Response objects inherit from ResponseBase, but even with the following ServiceKnownTypes in the WCF contract

 [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>))] 

When we load a message into the ResponseBase message collection, the following exception is thrown:

Error at position 1 of position 906. The element 'Http://schemas.datacontract.org/2004/07/CX.Framework.Common.BaseTypes:ResponseMessage' contains data from a type that maps to the name 'Http: //schemas.datacontract .org / 2004/07 / CX.Framework.Common.BaseTypes: WarnMessage. Deserializer does not know any type that maps to this name. Consider using a DataContractResolver or add a type corresponding to "WarnMessage" to the list of known types β€” for example, using KnownTypeAttribute or adding it to the list of known types passed to the DataContractSerializer.

We did everything from ServiceKnownType to XMLInclude on derived types. I have lost a little how to solve this problem, and I will be grateful for any help that anyone can provide.

+7
source share
1 answer

A few things:

1) [XmlInclude] will not affect DataContractSerializer , it is used only by XmlSerializer .

2) As the commentator "flem" said, I would use [KnownType] directly on ResponseMessage instead of [ServiceKnownType] in the service.

3) I don’t remember if the DataContractSerializer looking for the [KnownType] type for [Serializable] . At least for testing, now try using [DataContract] instead (as well as attributes of data members with [DataMember] ) if # 2 above doesn't help.

+5
source

All Articles