是否有一个原因序列化时,装饰着XmlInclude一个基类仍然会抛出一个类型未知的例外? [英] Is there a reason why a base class decorated with XmlInclude would still throw a type unknown exception when serialized?

查看:229
本文介绍了是否有一个原因序列化时,装饰着XmlInclude一个基类仍然会抛出一个类型未知的例外?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我将简化code,以节省空间,但什么是presented确实说明的核心问题。

我有其中有一个属性,它是一个基类的类。有可能被分配到该属性3派生类。

如果我给你任何的派生类的容器,并尝试序列化容器,XmlSerializer的引发可怕的:

  

X型是没有预料到。使用XmlInclude或SoapInclude属性来指定不知道静态类型。

不过我的基类是已经装修与属性,这样我估计,必须有一个额外的隐藏的要求。

本非常奇怪的是,默认的WCF序列化与这个类层次结构没有问题。

容器类

  [DataContract]
[XmlRoot(的ElementName =交易,命名空间= Constants.Namespace)
公共类PaymentSummaryRequest:CommandRequest
{
    [数据成员]
    公共PaymentSummary摘要{获得;组; }

    公共PaymentSummaryRequest()
    {
        机制= CommandMechanism.PaymentSummary;
    }
}
 

的基类

  [DataContract]
[XmlInclude(typeof运算(xPaymentSummary))]
[XmlInclude(typeof运算(yPaymentSummary))]
[XmlInclude(typeof运算(zPaymentSummary))]
[KnownType(typeof运算(xPaymentSummary))]
[KnownType(typeof运算(yPaymentSummary))]
[KnownType(typeof运算(zPaymentSummary))]
公共抽象类PaymentSummary
{
}
 

一个派生类

  [DataContract]
公共类xPaymentSummary:PaymentSummary
{
}
 

序列化code

 无功序列化=新的XmlSerializer(typeof运算(PaymentSummaryRequest));
serializer.Serialize(Console.Out,新PaymentSummaryRequest {摘要=新xPaymentSummary {}});
 

的异常

  

System.InvalidOperationException:   时出错生成XML文档。 --->   System.InvalidOperationException:类型xPaymentSummary是没有预料到。   使用XmlInclude或SoapInclude属性来指定未静态已知类型。在

     
    

Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriterPaymentSummaryRequest.Write13_PaymentSummary(String     N,字符串NS,PaymentSummary 0,     布尔ISNULLABLE,布尔needType)     在

         
      

Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriterPaymentSummaryRequest.Write14_PaymentSummaryRequest(String       N,字符串NS,PaymentSummaryRequest 0,       布尔ISNULLABLE,布尔needType)       在

             
        

Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriterPaymentSummaryRequest.Write15_TRANSACTION(Object         O) - 结束内部异常堆栈         跟踪---在

                 
          

System.Xml.Serialization.XmlSerializer.Serialize(的XmlWriter           XMLWriter的,对象o,           XmlSerializerNamespaces命名空间,           字符串的encodingStyle,字符串ID)在

                     
            

System.Xml.Serialization.XmlSerializer.Serialize(的TextWriter             的TextWriter,对象o,             XmlSerializerNamespaces命名空间)
            在UserQuery.RunUserAuthoredQuery()的             C:\用户\ Tedford \应用程序数据\本地的\ Temp \ uqacncyo.0.cs:行             47

          
        
      
    
  
解决方案

您所看到的问题是,因为 PaymentSummaryRequest 是设置命名空间。您可以删除的命名空间或添加一个命名空间的 PaymentSummary 类:

  [XmlRoot(命名空间= Constants.Namespace)
[XmlInclude(typeof运算(xxxPaymentSummary))]
公共抽象类PaymentSummary
{
}
 

由于@Tedford提到的命名空间低于他的评论只使用派​​生类型时,需要。

看起来生成XML序列化程序集的时候一样,因为根节点有一个命名空间集和基类没有它不包括XML在生成的序列化程序集的逻辑。

另一种方法来解决这一问题将是从类中删除命名空间声明自己并指定了的XmlSerializer 构造函数的命名空间:

 无功序列化=新的XmlSerializer(
    typeof运算(PaymentSummaryRequest)
    Constants.Namespace
);
 

I will simplify the code to save space but what is presented does illustrate the core problem.

I have a class which has a property that is a base type. There are 3 derived classes which could be assigned to that property.

If I assign any of the derived classes to the container and attempt to serialize the container, the XmlSerializer throws the dreaded:

"The type x was not expected. Use the XmlInclude or SoapInclude attribute to specify types that are not known statically."

However my base class is already decorated with that attribute so I figure there must be an additional "hidden" requirement.

The really odd part is that the default WCF serializer has no issues with this class hierarchy.

The Container class

[DataContract]
[XmlRoot(ElementName = "TRANSACTION", Namespace = Constants.Namespace)]
public class PaymentSummaryRequest : CommandRequest
{
    [DataMember]
    public PaymentSummary Summary { get; set; }

    public PaymentSummaryRequest()
    {
        Mechanism = CommandMechanism.PaymentSummary;
    }
}

The base class

[DataContract]
[XmlInclude(typeof(xPaymentSummary))]
[XmlInclude(typeof(yPaymentSummary))]
[XmlInclude(typeof(zPaymentSummary))]
[KnownType(typeof(xPaymentSummary))]
[KnownType(typeof(yPaymentSummary))]
[KnownType(typeof(zPaymentSummary))]
public abstract class PaymentSummary
{     
}

One of the derived classes

[DataContract]
public class xPaymentSummary : PaymentSummary
{
}

The serialization code

var serializer = new XmlSerializer(typeof(PaymentSummaryRequest));
serializer.Serialize(Console.Out,new PaymentSummaryRequest{Summary = new xPaymentSummary{}});

The Exception

System.InvalidOperationException: There was an error generating the XML document. ---> System.InvalidOperationException: The type xPaymentSummary was not expected. Use the XmlInclude or SoapInclude attribute to specify types that are not known statically. at

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) --- End of inner exception stack trace --- at

System.Xml.Serialization.XmlSerializer.Serialize(XmlWriter xmlWriter, Object o, XmlSerializerNamespaces namespaces, String encodingStyle, String id) at

System.Xml.Serialization.XmlSerializer.Serialize(TextWriter textWriter, Object o, XmlSerializerNamespaces namespaces)
at UserQuery.RunUserAuthoredQuery() in c:\Users\Tedford\AppData\Local\Temp\uqacncyo.0.cs:line 47

解决方案

The issue you are seeing is because the PaymentSummaryRequest is setting the Namespace. You can either remove the Namespace or add a Namespace to the PaymentSummary class:

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

As @Tedford mentions in his comment below the namespace is only required when using derived types.

It looks like when generating the XML Serialization assembly that since the Root node has a namespace set and the base class does not it is not including the XML Include logic in the generated serialization assembly.

Another approach to solving the issue would be to remove the namespace declarations from the classes themselves and specify the namespace on the XmlSerializer constructor:

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

这篇关于是否有一个原因序列化时,装饰着XmlInclude一个基类仍然会抛出一个类型未知的例外?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆