IXml可序列化和继承

本文关键字:继承 序列化 IXml | 更新日期: 2023-09-27 17:57:09

假设我有两个类,一个基类和一个派生类。它们是相当简单的类,主要只是充当数据结构(派生类显然稍微复杂一些)。

public class BaseUserSession
{
    // ... Various properties ...
}
public class DerivedUserSession : BaseUserSession
{
    // ... Even more properties ...
}

这些类需要序列化为 XML。现在,只需在类声明上方指定[Serializable]即可完成此操作,并且默认的 XML 序列化程序运行良好。

但是,实际上,有多个类继承自基类。我的目标是能够使基类可以使用任何派生类的序列化 XML。

我尝试了两种方法,但目前都不起作用。首先,使用本机 XML 序列化程序和基类中的一些控件属性。生成的 XML 如下所示:

<?xml version="1.0" encoding="utf-16"?>
<DerivedUserSession xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:SSO="www.mywebsite.com">
    <SSO:Id />
    <SSO:Authenticated>false</SSO:Authenticated>
    <SSO:Role />
    <EmailAddress />
    <FullName />
    <Street />
    <City />
    <State />
    <Zip />
    <DayPhone />
    <EveningPhone />
    <ErrorMessage />
    <Birthdate>0001-01-01T00:00:00</Birthdate>
    <CurrentControl>0</CurrentControl>
</DerivedUserSession>

SSO 为前缀的标记是从基类继承的标记。但是当我尝试将其反序列化为BaseUserSession对象时,它会抛出异常:System.InvalidOperationException: <DerivedUserSession xmlns=''> was not expected.

我还尝试使基类IXmlSerializable,并手动读取和写入所有XML。但是,派生类无法写出它们的属性,我真的不想为每个类实现IXmlSerializable

有没有更简单的方法可以做到这一点?

=

编辑=

我终于实现了一个相当丑陋的方法来实现这一点。这两个类继承自 base,它们都实现了 IXmlSerializable 。每个类(包括基类)都使用反射将其字段值(煞费苦心地...)写出到自己的XML层次结构中,并读回这些值。写入的第一个值始终来自基类。

每个应用程序还包括管理序列化为 XML 和返回的代码,从而提供简单的界面。会话本身现在除了简单地接受序列化的 XML 并将其存储在公共键下之外,不会执行任何其他操作。进出 XML 的序列化全部由应用程序处理,并且所有应用程序中都使用通用XmlRootAttribute来绕过InvalidOperationException

所以现在,当另一个应用程序尝试反序列化最初在其他应用程序中创建的 XML 时,它会设法在命中无法识别的元素之前读取公共基类值,此时它会去其他地方获取所需的值,这是可能的,因为它已经具有公共基值。

我需要阅读序列化原则...

IXml可序列化和继承

XmlSerialization 不是多态的(但是,成员属性与声明类一起使用;即,除非您使用 new 关键字否决成员(与 override 相反),否则您将"继承"序列化属性。

反序列化始终生成序列化的实际类型。这很有意义,真的。

好吧,我已经设法完成了你试图使用DataContractSerializer做的事情。

您应该将 KnownTypes 属性放在要序列化的基类上,或者更好的是使用 DataContractResolver 来查找派生类型。

我已经在网上看到了一个通用的实现,如果我再次找到它,我会在这里发布它。

编辑

在这里找到它

如果您需要更多帮助,请告诉我。