我已经看过很多关于.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 lists或XmlIgnoreAttribute documentation中看到它。
答案 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,所以反序列化器甚至不应该尝试设置它。