Xml 反序列化无法识别生成的代理派生类

发布于 2024-11-01 17:54:00 字数 2399 浏览 6 评论 0原文

我在尝试将 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

淡淡離愁欲言轉身 2024-11-08 17:54:00

我解决了我的问题。

首先,我从 InstallerConfig 类的 Preventions 属性中删除了所有 XML 装饰标记。这使得序列化后,XML 中派生类的元素不会显示为 ,而是显示为

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

I solved my problem.

First, I removed ALL XML decoration tags from Prerequisites property in InstallerConfig 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:

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());

That let the application code to cast any ModuleRequisite derived class to its corresponding type (defined in xsi:type XML property).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文