Używamy klasy bazowej dla wszystkich naszych DTO Response w naszej aplikacji. Klasa ma następujący podpis:WCF Klasa abstrakcyjna bazy z złożonym zbiorem typów abstrakcyjnych, które nie są uwzględniane do deserializacji w odpowiedzi na usługi
[Serializable]
public abstract class ResponseBase
{
public bool Successful { get; set; }
public List<ResponseMessage> Messages { get; set; }
//...Other code...
}
Zbiór wiadomości mogą być dowolne z następujących typów:
[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...
}
betonem wersjach:
[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; } }
}
obiekty Response
Wszystko DTO dziedziczyć ResponseBase jednak nawet z następującymi ServiceKnownTypes na kontrakcie WCF
[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>))]
Kiedy załadować wiadomość do kolekcji ResponseBase Wiadomości następujące pobiera wyjątek:
Błąd w linii 1 pozycja 906. Element „http://schemas.datacontract.org/2004/07/ CX.Framework.Common.BaseTypes: ResponseMessage " zawiera dane z typu, który odwzorowuje na nazwę " http://schemas.datacontract.org/2004/07/CX.Framework.Common.BaseTypes:WarnMessage ". Deserializator nie ma żadnej wiedzy o dowolnym typie mapującym do tej nazwy. Rozważ użycie DataContractResolver lub dodaj typ odpowiadający "WarnMessage" do listy znanych typów - na przykład za pomocą atrybutu KnownTypeAttribute lub dodając go do listy znanych typów przekazanych do DataContractSerializer.
Zrobiliśmy wszystko, od ServiceKnownType do XMLInclude na typach pochodnych. Jestem trochę zagubiony, jak rozwiązać ten problem i byłbym wdzięczny za pomoc, którą każdy może zapewnić.
Spróbuj wprowadzić znane atrybuty typów dla ResponseMessage w definicji klasy ResponseBase. Robię podobnie (używając '[DataContract]' i '[KnownType]') i wymaga to, aby klasa, która ma członków typu polimorficznego, była dekorowana '[KnownType (typeof (DerivedTypeA))]'. –
Powinien opublikować jako odpowiedź @flem! To właśnie zadziałało i było pierwszą odpowiedzią na pytanie, uderzeniem w komentarz, ale dziękuję za odpowiedź. – VulgarBinary
Przyjemność ... Tu nie chodzi tylko o przedstawiciela! ;) –