【问题标题】:Xml Deserialization not recognising generated proxy derived classesXml 反序列化无法识别生成的代理派生类
【发布时间】:2011-08-07 21:22:15
【问题描述】:

在尝试将 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 */ }

    ...
}

FileExistsRequisiteRegistryKeyExistsRequisite 都派生自基础 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。

我做错了什么?对这个麻烦感到非常沮丧:-(

提前致谢。

【问题讨论】:

  • 您能否阐明“一个 WCF 4.0 服务共享这些类型”的意思?您是说InstallerConfig 是合同的一部分,还是说客户端实际上引用了包含InstallerConfig 的同一个DLL 作为服务?如果是前者,那么客户端看到的 InstallerConfig 是根据服务传递的定义构建的新类 - 不是您的原始类,因此将缺少属性。
  • 因此,您有两个应用程序,并且 XML 的反序列化在其中一个中起作用,而在另一个中不起作用。对吗?
  • @Basiclife :对不起,意思是 InstallerConfig 是合同的一部分。但是这种属性信息的丢失只发生在派生的属性类型上。事实上,我正在为 InstallerConfig 属性使用其他通用和非通用集合(此处省略),并且我成功地对它们进行了序列化和反序列化。
  • @Cheeso 就是这样。反序列化在 WCF 端正常工作,但在客户端不能正常工作
  • 如果您在客户端应用程序中右键单击Go To Definition,然后在InstallerConfig 上单击,那么该类有什么明显的问题吗?它是否具有您期望的所有属性/特性? i 是否与 WCF 端等效项相同?

标签: wcf inheritance xml-serialization deserialization derived-class


【解决方案1】:

我解决了我的问题。

首先,我从InstallerConfig 类的Prerequisites 属性中删除了所有XML 装饰标签。这使得在序列化之后,来自 XML 中派生类的元素不会显示为 &lt;DERIVEDCLASSNAME&gt;&lt;/DERIVEDCLASSNAME&gt;,而是显示为 &lt;BASECLASSNAME xsi:type="DERIVEDCLASSNAME"&gt;&lt;/BASECLASSNAME&gt;

在客户端,反序列化时,我在 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 属性中定义)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-25
    • 2017-06-24
    • 1970-01-01
    相关资源
    最近更新 更多