代码之家  ›  专栏  ›  技术社区  ›  Tom Mayfield

.NET 3.5 SP1中的XmlSerializer更改

  •  5
  • Tom Mayfield  · 技术社区  · 16 年前

    我已经看过很多关于.NET3.5SP1中的更改的文章,但是偶然发现了一篇昨天还没有看到文档的文章。在我的机器上,从VS、msbuild命令行,所有代码都运行得很好,但在构建服务器(运行.NET3.5RTM)上失败了。

    [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:

    无法生成临时类(结果=1)。 错误CS0200:无法将属性或索引器“ConsoleApplication2.Foo.Bar”分配给--它是只读的

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

    我的google fu显然无法找到这些变化的文档。在任何地方都有一个变更列表,列出了这个变更(以及类似的幕后变更,可能会跳起来喊“明白了”)?这是一个bug还是一个特性?

    :在SP1中,如果我添加了 <Bar /> 元素,或为Bar属性设置[XmlElement],则不会对其进行反序列化。它在SP1之前尝试反序列化时不会失败——在构造XmlSerializer时会引发异常。

    这使我更倾向于将其视为一个bug,特别是如果我为Foo.Bar设置了[xmlement]属性。如果它无法执行我要求它执行的操作,它应该抛出一个异常,而不是默默地忽略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 lists ,或 XmlIgnoreAttribute documentation .

    2 回复  |  直到 16 年前
        1
  •  4
  •   TonyB    16 年前

    在SP1中,foo.Bar属性是否正确反序列化?

    在SP1之前的版本中,您将无法反序列化对象,因为Bar属性的set方法是私有的,因此XmlSerializer无法设置该值。我不确定SP1是如何实现的。

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

    这将把XmlSerializer生成的类放入c:\foo中,这样您就可以看到它在SP1和RTM中做了什么

        2
  •  0
  •   Jesse C. Slicer    16 年前

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