XML 反序列化程序命名空间与旧文件冲突



我在 VB.NET 的遗留系统中工作。它通过使用 XMLSerializer 并传入对象,将数据存储在本地 XML 文件中。为了读取数据,它以相同的方式反序列化回对象。

我们没有显式架构或 XML 命名空间。我知道这远非理想,我知道如果我们更改任何属性的名称或顺序,那么我们就会破坏向后兼容性。但是我们被这个基本系统和许多现有文件所困,它必须能够读写。

我没有触及正在序列化的对象的任何属性。但我确实开始在应用程序的另一部分使用 System.Drawing.Point。现在,当我尝试序列化或反序列化时,我收到 InvalidOperationException 并显示以下消息:

类型"System.Windows.Point"和"System.Drawing.Point"都使用 XML 类型名称"点",来自命名空间"。使用 XML 属性可以 为类型指定唯一的 XML 名称和/或命名空间。

我承认我不明白系统为什么突然决定这种类型是模棱两可的。引发错误的类的属性专门声明为 System.Windows.Point。在任何地方,都不会序列化或反序列化另一个点的实例。

我已经搜索了很多关于这个异常,但我看到的讨论似乎都与 Web 服务和开发人员命名的类有关。答案似乎是"重命名类"或"使用 XML 属性为您的类型指定新的 XML 命名空间"。

我想我不能做这两件事。我无法重命名 System.Windows.Point。我无法更改系统期望写入或读取的任何标记,因为我无法破坏与过去写入的任何文件的向后兼容性。

当我没有做任何事情来更改XML时,这个错误是如何开始出现的?如何在不破坏我访问大量现有 XML 文件的能力的情况下修复它?

编辑:XML 文件本身不会在任何地方引用"点"。XML 如下所示:

<MyClass xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <Segment>
        <ID>0</ID>
        <Location>
            <X>37</X>
            <Y>330</Y>
        </Location>
        (other properties)
    </Segment>
    <Segment>
    .....
</MyClass>

已解决。

事实证明,写入 XML 的某些内容确实发生了变化。一个很少实例化的小对象将成员声明为"Point",而没有进一步指定类型,编译器默认使用 System.Windows.Point。当我开始引用System.Drawing时,该属性静默地更改了,因此它使用的是Drawing.Point。(我不知道为什么编译器没有开始抱怨这是一个模棱两可的类型名称。

无论如何,当序列化程序尝试写入 Drawing.Point 类型的属性时,在已经编写了 Windows.Point 类型的属性后,它意识到名称冲突并例外。

解决方案是将两个属性显式键入同一事物。

最新更新