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; }
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 {
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.
VulgarBinary
source share