.NET 3.5 SP1中XmlSerializer的更改

5

我看到了很多关于.NET 3.5 SP1变化的帖子,但昨天我偶然发现了一个没有文档记录的问题。我在我的机器上使用VS、msbuild命令行等成功运行了代码,但在运行.NET 3.5 RTM的构建服务器上失败了。

[XmlRoot("foo")]
public class Foo
{
    static void Main()
    {
        XmlSerializer serializer = new XmlSerializer(typeof(Foo));

        string xml = @"<foo name='ack' />";
        using (StringReader sr = new StringReader(xml))
        {
            Foo foo = serializer.Deserialize(sr) as Foo;
        }
    }

    [XmlAttribute("name")]
    public string Name { get; set; }

    public Foo Bar { get; private set; }
}

在SP1中,上述代码可以正常运行。在RTM中,您会收到一个InvalidOperationException:
无法生成临时类(result=1)。 错误CS0200:属性或索引器'ConsoleApplication2.Foo.Bar'不能被分配--它是只读的
当然,只需添加[XmlIgnore]到Bar属性就可以使其在RTM下运行。
我的谷歌搜索似乎没有找到这些更改的文档。是否有任何变更列表列出了这种变更(以及可能会跳出来并大声喊叫“gotcha”的类似底层更改)?这是一个错误还是一个特性?
编辑:在SP1中,如果我添加了一个元素,或者为Bar属性设置[XmlElement],它将无法反序列化。当它尝试反序列化时,它不会在pre-SP1失败--它在构造XmlSerializer时抛出异常。
这让我更倾向于认为这是一个 bug,特别是当我为 Foo.Bar 设置 [XmlElement] 属性时。如果它无法完成我的要求,它应该抛出异常而不是静默忽略 Foo.Bar。其他无效的 XML 序列化属性组合/设置会导致异常。

编辑: 感谢 TonyB,我之前不知道如何设置临时文件位置。对于将来遇到类似问题的人,您需要一个额外的配置标志:

<system.diagnostics>
  <switches>
    <add name="XmlSerialization.Compilation" value="1" />
  </switches>
</system.diagnostics>
<system.xml.serialization>
  <xmlSerializer tempFilesLocation="c:\\foo"/>
</system.xml.serialization>

即使在Bar属性上设置了[XmlElement]属性,生成的序列化程序集中也没有提到它,这很明显是一个被默默吞噬的错误(也就是一个bug)。要么设计师已经决定对于无法设置的属性不再需要[XmlIgnore]--你会期望在发布说明、变更列表XmlIgnoreAttribute文档中看到这一点。
2个回答

4

在 SP1 中,foo.Bar 属性是否能够得到正确的反序列化?

在 SP1 之前,你无法反序列化该对象,因为 Bar 属性的 set 方法是私有的,所以 XmlSerializer 没有设置该值的方法。我不确定 SP1 是如何实现的。

你可以尝试将下面的内容添加到你的 web.config/app.config 文件中:

<system.xml.serialization> 
  <xmlSerializer tempFilesLocation="c:\\foo"/> 
</system.xml.serialization> 

这将把XmlSerializer生成的类放入c:\foo中,以便您可以看到它在SP1和RTM中执行的操作。


1
这似乎无法解决.NET 4中的问题。 - Levitikon

0

我相当喜欢这种新的行为,因为XML文档中没有提到Bar,所以反序列化程序甚至不应该尝试设置它。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接