Tom*_*eld 5 xml serialization .net-3.5
我看过很多关于.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; }
}
Run Code Online (Sandbox Code Playgroud)
在SP1中,上面的代码运行得很好.在RTM中,您会收到InvalidOperationException:
无法生成临时类(result = 1).错误CS0200:属性或索引器'ConsoleApplication2.Foo.Bar'无法分配 - 它是只读的
当然,使其在RTM下运行所需的只是将[XmlIgnore]添加到Bar属性.
我的google fu显然无法找到这些变化的文档.是否有任何列出此更改的更改列表(以及类似的引擎盖下的更改,可能会跳起来并大喊"问题")?这是一个错误还是一个功能?
编辑:在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>
Run Code Online (Sandbox Code Playgroud)
即使在Bar属性上设置[XmlElement]属性,也没有在生成的序列化程序集中提及它 - 这相当坚定地将其置于一个静默吞噬错误(也就是一个bug)的领域.无论是设计师还是设计者已经决定[XmlIgnore]不再需要无法设置的属性 - 并且您希望在发行说明,更改列表或XmlIgnoreAttribute文档中看到它.
在 SP1 中 foo.Bar 属性是否正确反序列化?
在 SP1 之前的版本中,您将无法反序列化该对象,因为 Bar 属性的 set 方法是私有的,因此 XmlSerializer 无法设置该值。我不确定 SP1 是如何实现这一目标的。
您可以尝试将其添加到您的 web.config/app.config
<system.xml.serialization>
<xmlSerializer tempFilesLocation="c:\\foo"/>
</system.xml.serialization>
Run Code Online (Sandbox Code Playgroud)
这会将 XmlSerializer 生成的类放入 c:\foo 中,这样您就可以看到它在 SP1 与 RTM 中做了什么