我正在努力将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
和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应用程序,其中WCF由Web引用引用。当我尝试反序列化以前序列化的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]
)作为Prerequisite
字段的值,当XML实际上有两个元素都来自ModuleRequisite时。 / p>
我做错了什么?对这个麻烦感到非常沮丧: - (
提前致谢。
答案 0 :(得分:0)
我解决了我的问题。
首先,我从Prerequisites
类的InstallerConfig
属性中删除了所有XML装饰标记。这使得在序列化之后,XML中派生类的元素不会显示为<DERIVEDCLASSNAME></DERIVEDCLASSNAME>
,而是显示为<BASECLASSNAME xsi:type="DERIVEDCLASSNAME"></BASECLASSNAME>
。
在客户端,反序列化时,我在XmlSerializer构造函数中添加了派生类作为额外类型:
List<Type> extraTypes = new List<Type>() {
extraTypes.Add(typeof(WCFWebReference.FileExistsRequisite)),
extraTypes.Add(typeof(WCFWebReference.RegistryKeyExistsRequisite))
};
XmlSerializer serializer = new XmlSerializer(
typeof(WCFWebReference.InstallerConfig), extraTypes.ToArray());
让应用程序代码将任何ModuleRequisite
派生类强制转换为其对应的类型(在xsi:type
XML属性中定义)。