我看到了很多关于.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文档中看到这一点。