我看过很多关于 .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:
无法生成临时类(结果=1)。错误 CS0200:无法将属性或索引器“ConsoleApplication2.Foo.Bar”分配给 -- 它是只读的
当然,让它在 RTM 下运行所需的只是将 [XmlIgnore] 添加到 Bar 属性。
我的 google fu 显然无法找到此类更改的文档。是否有任何地方的更改列表列出了此更改(以及类似的可能会跳起来并大喊“gotcha”的引擎盖下的更改)?这是错误还是功能?
编辑:在 SP1 中,如果我添加了一个<Bar />
元素,或者为 Bar 属性设置了 [XmlElement],它不会被反序列化。它在尝试反序列化时不会在 SP1 之前失败 - 在构造 XmlSerializer 时会引发异常。
这让我更倾向于认为它是一个错误,特别是如果我为 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] 属性,在生成的序列化程序集中也没有提到它——这相当坚定地把它放在了一个默默吞下的错误(又名错误)的领域。或者设计者已经决定 [XmlIgnore] 对于无法设置的属性不再是必需的——您希望在发行说明、更改列表或XmlIgnoreAttribute 文档中看到这一点。