我有一个xml文件存储有关测试的详细信息
<TestUnit>
<DataDetails>
<Chart>
...............
</Chart>
</DataDetails>
</TestUnit>
此xml先前已配置且已部署。 现在要求在datadetails中添加新的扩展图表节点,这是图表元素的数组。我们已相应地更新了架构,但在验证以前创建的XML时遇到错误,因为它没有在架构中添加新节点。
新XML看起来像
<TestUnit>
<DataDetails>
<Chart>
...............
</Chart>
<ExtendedChart>
</ExtendedChart>
</DataDetails>
</TestUnit>
对于新创建的XML模式工作正常,但对于以前添加的XML,它不起作用。 投掷例外 捕获到System.Runtime.Serialization.SerializationException 的HResult = -2146233076 消息=第1行位置38724中的错误。不期望来自命名空间“http://schemas.datacontract.org/2004/07/TestDataObjects”的“元素”'filesField'。期待元素'extendedChartField'。
答案 0 :(得分:0)
如果您的XML有不同的布局,我建议您实现ISerializable接口。通过实现它,您将不得不对序列化和反序列化进行编码,但这并不困难。您只需将条件序列化放在不常用的字段上。
如果需要,请随时提出帮助。
迪米特里。
答案 1 :(得分:0)
正如我的评论中所说,这是因为DataContractSerializer
期望按字母顺序排列相同级别的元素。
请查看有关数据合同版本控制的this article on MSDN。
如上所述,可以设置EmitDefaultValue=false
,如果提供了默认值(通常为null或0),它将告诉DataContractSerializer
不输出元素,但正如文章中提到的,这不是推荐使用。
相反,使用本文中提到的示例,您可以创建两个不同的类 - 每个版本一个,为Name
的{{1}}属性添加公共值,如下所示:
DataContractAttribute
版本2端点可以成功将数据发送到版本1端点。序列化Car数据协定的第2版会产生类似于以下内容的XML。
// Version 1 of a data contract, on machine V1.
[DataContract(Name = "Car")]
public class CarV1
{
[DataMember]
private string Model;
}
// Version 2 of the same data contract, on machine V2.
[DataContract(Name = "Car")]
public class CarV2
{
[DataMember]
private string Model;
[DataMember]
private int HorsePower;
}
V1上的反序列化引擎找不到HorsePower字段的匹配数据成员,并丢弃该数据。
为了向后兼容:
版本1端点可以将数据发送到版本2端点。序列化Car数据协定的第1版会产生类似于以下内容的XML。
<Car>
<Model>Porsche</Model>
<HorsePower>300</HorsePower>
</Car>
版本2反序列化器不知道将HorsePower字段设置为什么,因为传入的XML中没有匹配的数据。 相反,该字段设置为默认值0。
在这个例子中,我们使用两个不同的类,因此它们都可以在同一范围内引用。在实践中,这些可能是同一个类,但版本之间略有不同。