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

时间:2013-10-21 05:37:13

标签: .net xml serialization

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

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

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

  

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

我承认我不明白系统突然决定这种类型是不明确的。抛出错误的类的属性专门声明为System.Windows.Point。任何地方都没有其他Point的实例被序列化或反序列化。

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

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

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

编辑: XML文件本身并未在任何地方引用“Point”。 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>

1 个答案:

答案 0 :(得分:1)

解决。

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

无论如何,当序列化程序尝试编写Drawing.Point类型的属性时,在已经编写了类型为Windows.Point的属性之后,它实现了名称冲突和例外。

解决方案是明确地将两个属性键入同一个属性。