有一个原因,为什么用XmlInclude装饰的基类仍然会在序列化时抛出一个types未知的exception?

我将简化代码以节省空间,但所呈现的内容确实说明了核心问题。

我有一个类是有一个属性是一个基types。 有3个派生类可以分配给该属性。

如果我将任何派生类分配给容器并试图序列化容器,则XmlSerializer将引发可怕的:

“typesx不是预期的,使用XmlInclude或SoapInclude属性指定静态未知的types。

然而,我的基类已经用该属性装饰,所以我认为必须有一个额外的“隐藏”的要求。

真奇怪的是,默认的WCF序列化程序对这个类层次结构没有任何问题。

Container类

[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:typesxPaymentSummary不是预期的。 使用XmlInclude或SoapInclude属性指定静态未知的types。 在

Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriterPaymentSummaryRequest.Write13_PaymentSummary(String n,String ns,PaymentSummary o,Boolean isNullable,Boolean needType)at

Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriterPaymentSummaryRequest.Write14_PaymentSummaryRequest(String n,String ns,PaymentSummaryRequest o,Boolean isNullable,Boolean needType)at

Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriterPaymentSummaryRequest.Write15_TRANSACTION(Object o)—内部exception堆栈跟踪结束—在

System.Xml.Serialization.XmlSerializer.Serialize(XmlWriter xmlWriter,Object o,XmlSerializerNamespaces命名空间,stringencodingStyle,stringid)在

System.Xml.Serialization.XmlSerializer.Serialize(TextWriter textWriter,Object o,XmlSerializerNamespaces命名空间)
在c:\ Users \ Tedford \ AppData \ Local \ Temp \ uqacncyo.0.cs中的UserQuery.RunUserAuthoredQuery()中:第47行

您看到的问题是因为PaymentSummaryRequest正在设置命名空间。 您可以删除名称空间,也可以将名称空间添加到PaymentSummary类中:

 [XmlRoot(Namespace = Constants.Namespace)] [XmlInclude(typeof(xxxPaymentSummary))] public abstract class PaymentSummary { } 

正如@Tedford在他的评论中提到的那样,只有在使用派生types时才需要命名空间。

它看起来像生成XML序列化程序集时那样,由于根节点具有名称空间集,而基类不包含生成的序列化程序集中的XML包含逻辑。

解决此问题的另一种方法是从类本身删除名称空间声明,并在XmlSerializer构造函数中指定名称空间:

 var serializer = new XmlSerializer( typeof(PaymentSummaryRequest), Constants.Namespace );