关于xml:.NET 3.5 SP1中的xml:XmlSerializer更改

关于xml:.NET 3.5 SP1中的xml:XmlSerializer更改

XmlSerializer changes in .NET 3.5 SP1

我已经看过很多有关.NET 3.5 SP1更改的帖子,但偶然发现了昨天尚未见到的文档。我的代码在VS,msbuild命令行等所有机器上都可以在我的机器上正常运行,但是在构建服务器(运行.NET 3.5 RTM)上却失败了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
[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:

Unable to generate a temporary class (result=1).
error CS0200: Property or indexer 'ConsoleApplication2.Foo.Bar' cannot be assign to -- it is read only

当然,要使其在RTM下运行,所需要做的就是在Bar属性中添加[XmlIgnore]。

我的Google Fu显然不适合查找此类更改的文档。是否有列出此更改的更改列表(以及可能跳起来并大喊"陷阱"的类似的内部更改)?这是错误还是功能?

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

这使我更倾向于将其视为错误,尤其是如果我为Foo.Bar设置了[XmlElement]属性。如果它无法执行我要求的操作,则应该抛出异常,而不是无视Foo.Bar。 XML序列化属性的其他无效组合/设置会导致异常。

编辑:谢谢TonyB,我不知道如何设置临时文件的位置。对于将来遇到类似问题的用户,您确实需要一个附加的配置标志:

1
2
3
4
5
6
7
8
<system.diagnostics>
  <switches>
   
  </switches>
</system.diagnostics>
<system.xml.serialization>
  <xmlSerializer tempFilesLocation="c:\\\\foo"/>
</system.xml.serialization>

即使在Bar属性上设置了[XmlElement]属性,在生成的序列化程序集中也没有提及它-相当牢固地将其置于无声吞没的错误(又称错误)领域。或者是设计者决定,对于无法设置的属性,不再需要[XmlIgnore]了-您希望在发行说明,更改列表或XmlIgnoreAttribute文档中看到这一点。


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

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

您可以尝试将其添加到web.config / app.config

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

这会将XmlSerializer生成的类放入c:\\\\ foo,因此您可以看到它在SP1和RTM中的作用。


我更喜欢这种新的(?)行为,因为XML文档中没有任何提及Bar的信息,因此反序列化器甚至不应尝试对其进行设置。


推荐阅读