Xml 反序列化无法识别生成的代理派生类
我在尝试将 XML 反序列化为具有派生类型的自动生成代理类时遇到了严重的头痛。
这是我的场景(使用 Xml.Serialization
)
一个 WCF 4.0 服务共享(作为合同的一部分)这些类型:
[XmlRootAttribute(Namespace = "", IsNullable = false)]
public class InstallerConfig
{
[XmlArray]
[XmlArrayItem(typeof(FileExistsRequisite))]
[XmlArrayItem(typeof(RegistryKeyExistsRequisite))]
public List<ModuleRequisite> Prerequisites { /* getter and setter */ }
...
}
FileExistsRequisite
和 < code>RegistryKeyExistsRequisite 均派生自基础 ModuleRequisite
。它们的定义如下:
[XmlInclude(typeof(FileExistsRequisite))]
[XmlInclude(typeof(RegistryKeyExistsRequisite))]
public class ModuleRequisite
{
/* some properties here */
}
public class FileExistsRequisite : ModuleRequisite
{
/* some properties here */
}
public class RegistryKeyExistsRequisite : ModuleRequisite
{
/* some properties here */
}
如果我尝试序列化然后反序列化一个 InstallerConfig 实例,它就会正常工作(序列化和反序列化都按预期工作)。
这是生成的 XML 文件:
<?xml version="1.0" encoding="utf-8"?>
<InstallerConfig xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<Prerequisites>
<RegistryKeyExistsRequisite>
<RequisiteOrder>1</RequisiteOrder>
<!-- Some other elements with their values -->
</RegistryKeyExistsRequisite>
<FileExistsRequisite>
<RequisiteOrder>2</RequisiteOrder>
<!-- Some other elements with their values -->
</FileExistsRequisite>
</Prerequisites>
</InstallerConfig>
但是,另一方面,我有一个 NET 2.0 WinForms 应用程序,其中包含由 Web 引用引用的 WCF。当我尝试反序列化以前序列化的 XML 文件时:
XmlSerializer serializer = new XmlSerializer(typeof(WCFWebReference.InstallerConfig));
XmlTextReader stream = new XmlTextReader("deserializedXML.xml");
WCFWebReference.InstallerConfig desInstallerConfig = (WCFWebReference.InstallerConfig)serializer.Deserialize(stream);
创建的 desInstallerConfig
对象具有一个空的 ModuleRequisite
对象数组 (MyNamespace.WCFWebReference.ModuleRequisite[0]
) 作为 Precession
字段的值,当 XML 实际上有两个都派生自 ModuleRequisite 的元素时。
我做错了什么?对这个麻烦非常沮丧:-(
提前致谢。
I'm having severe headaches trying to deserialize an XML into an auto-generated proxy class with derived types.
This is my scenario (working with Xml.Serialization
)
One WCF 4.0 service sharing (as part of the contract) these type:
[XmlRootAttribute(Namespace = "", IsNullable = false)]
public class InstallerConfig
{
[XmlArray]
[XmlArrayItem(typeof(FileExistsRequisite))]
[XmlArrayItem(typeof(RegistryKeyExistsRequisite))]
public List<ModuleRequisite> Prerequisites { /* getter and setter */ }
...
}
FileExistsRequisite
and RegistryKeyExistsRequisite
are both derived from base ModuleRequisite
. All of them are defined as follows:
[XmlInclude(typeof(FileExistsRequisite))]
[XmlInclude(typeof(RegistryKeyExistsRequisite))]
public class ModuleRequisite
{
/* some properties here */
}
public class FileExistsRequisite : ModuleRequisite
{
/* some properties here */
}
public class RegistryKeyExistsRequisite : ModuleRequisite
{
/* some properties here */
}
If I try to serialize and then deserialize an InstallerConfig
instance it just work (both serialization and deserialization work as expected).
This is the resultant XML file:
<?xml version="1.0" encoding="utf-8"?>
<InstallerConfig xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<Prerequisites>
<RegistryKeyExistsRequisite>
<RequisiteOrder>1</RequisiteOrder>
<!-- Some other elements with their values -->
</RegistryKeyExistsRequisite>
<FileExistsRequisite>
<RequisiteOrder>2</RequisiteOrder>
<!-- Some other elements with their values -->
</FileExistsRequisite>
</Prerequisites>
</InstallerConfig>
However, in the other hand I have a NET 2.0 WinForms Application with WCF referenced by a web reference. When I try to deserialize previously serialized XML file:
XmlSerializer serializer = new XmlSerializer(typeof(WCFWebReference.InstallerConfig));
XmlTextReader stream = new XmlTextReader("deserializedXML.xml");
WCFWebReference.InstallerConfig desInstallerConfig = (WCFWebReference.InstallerConfig)serializer.Deserialize(stream);
Created desInstallerConfig
object has an empty array of ModuleRequisite
objects (MyNamespace.WCFWebReference.ModuleRequisite[0]
) as value for Prerequisite
field, when XML actually has two elements both derived from ModuleRequisite.
What am I doing wrong? So much frustrated with this trouble :-(
Thanks in advance.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我解决了我的问题。
首先,我从
InstallerConfig
类的Preventions
属性中删除了所有 XML 装饰标记。这使得序列化后,XML 中派生类的元素不会显示为
,而是显示为
。在客户端,反序列化时,我在 XmlSerializer 构造函数中添加了派生类作为额外类型:
这使得应用程序代码可以将任何
ModuleRequisite
派生类转换为其相应的类型(在xsi:type XML 属性)。
I solved my problem.
First, I removed ALL XML decoration tags from
Prerequisites
property inInstallerConfig
class. That made that, after serialization, elements from derived classes in XML not appearing as<DERIVEDCLASSNAME></DERIVEDCLASSNAME>
, but as<BASECLASSNAME xsi:type="DERIVEDCLASSNAME"></BASECLASSNAME>
.At client, when deserializing, I added derived classes as extra types in XmlSerializer constructor:
That let the application code to cast any
ModuleRequisite
derived class to its corresponding type (defined inxsi:type
XML property).