Я упрощу код, чтобы сэкономить место, но представленное иллюстрирует основную проблему.
У меня есть класс, который имеет свойство, которое является базовым типом. Существует 3 производных класса, которые могут быть назначены этому свойству.
Если я назначу какой-либо из производных классов контейнеру и попытаюсь сериализовать контейнер, XmlSerializer выбрасывает ужасный:
"Тип x не ожидался. Используйте атрибут XmlInclude или SoapInclude, чтобы указать типы, которые не известны статически".
Однако мой базовый класс уже украшен этим атрибутом, поэтому я считаю, что должно быть дополнительное "скрытое" требование.
Нечетная часть состоит в том, что по умолчанию для сериализатора WCF нет проблем с этой иерархией классов.
Класс контейнера
[DataContract]
[XmlRoot(ElementName = "TRANSACTION", Namespace = Constants.Namespace)]
public class PaymentSummaryRequest : CommandRequest
{
[DataMember]
public PaymentSummary Summary { get; set; }
public PaymentSummaryRequest()
{
Mechanism = CommandMechanism.PaymentSummary;
}
}
Базовый класс
[DataContract]
[XmlInclude(typeof(xPaymentSummary))]
[XmlInclude(typeof(yPaymentSummary))]
[XmlInclude(typeof(zPaymentSummary))]
[KnownType(typeof(xPaymentSummary))]
[KnownType(typeof(yPaymentSummary))]
[KnownType(typeof(zPaymentSummary))]
public abstract class PaymentSummary
{
}
Один из производных классов
[DataContract]
public class xPaymentSummary : PaymentSummary
{
}
Код сериализации
var serializer = new XmlSerializer(typeof(PaymentSummaryRequest));
serializer.Serialize(Console.Out,new PaymentSummaryRequest{Summary = new xPaymentSummary{}});
Исключение
System.InvalidOperationException: При создании XML-документа произошла ошибка. --- > System.InvalidOperationException: Тип xPaymentSummary не ожидался. Используйте атрибут XmlInclude или SoapInclude, чтобы указать типы, которые не известны статически. в
Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriterPaymentSummaryRequest.Write13_PaymentSummary (String n, String ns, PaymentSummary o, Boolean isNullable, Boolean needType) в
Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriterPaymentSummaryRequest.Write14_PaymentSummaryRequest (String n, String ns, PaymentSummaryRequest o, Boolean isNullable, Boolean needType) в
Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriterPaymentSummaryRequest.Write15_TRANSACTION (Объект o) --- Конец внутреннего стека исключений trace --- at
System.Xml.Serialization.XmlSerializer.Serialize(XmlWriter xmlWriter, Object o, Пространства имен XmlSerializerNamespaces, String encodingStyle, String id) в
System.Xml.Serialization.XmlSerializer.Serialize(TextWriter textWriter, Object o, Пространства имен XmlSerializerNamespaces)
в UserQuery.RunUserAuthoredQuery() в C:\Users\Tedford\AppData\Local\Temp\uqacncyo.0.cs: линия 47