.NET 3.5 SP1中的XmlSerializer更改

时间:2008-08-29 18:15:05

标签: xml serialization .net-3.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'无法分配 - 它是只读的

当然,使其在RTM下运行所需的只是将[XmlIgnore]添加到Bar属性。

我的google fu显然无法找到这些变化的文档。是否有任何列出此更改的更改列表(以及类似的引擎盖下的更改,可能会跳起来并喊出“gotcha”)?这是一个错误还是一个功能?

编辑:在SP1中,如果我添加了<Bar />元素,或者为Bar属性设置了[XmlElement],则不会反序列化。它在尝试反序列化时不会在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]不再需要无法设置的属性 - 并且您希望在发行说明change listsXmlIgnoreAttribute documentation中看到它。

2 个答案:

答案 0 :(得分: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 :(得分:0)

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