为什么DataContractSerializer按字母顺序排序XML?

我有以下数据合同:

namespace Wcf.Contracts.Data { [DataContract] public class Presence { [DataMember] public int Id { get; set; } [DataMember] public DateTime? From { get; set; } [DataMember] public DateTime? To { get; set; } [DataMember] public TimeSpan? BreakPeriod { get; set; } } } 

Presence实例序列化为XML并将相同的XML反序列化为Presence实例效果很好。 但反序列化表示序列化Presence对象的字符串变量给了我奇怪的行为。 某些属性获取默认值而不是XML中的指定值。 我发现XML中代表Presence属性的元素必须按字母顺序排列。

例如,在这段代码中

 var dcs = new System.Runtime.Serialization.DataContractSerializer(typeof(Wcf.Contracts.Data.Presence)); var xml1 = @"  PT30M 2013-08-21T10:00:00Z 2013-08-21T15:00:00Z 85 "; var xr1 = System.Xml.XmlReader.Create(new System.IO.StringReader(xml1)); var p1 = dcs.ReadObject(xr1) as Wcf.Contracts.Data.Presence; var xml2 = @"  85 2013-08-21T10:00:00Z 2013-08-21T15:00:00Z PT30M "; var xr2 = System.Xml.XmlReader.Create(new System.IO.StringReader(xml2)); var p2 = dcs.ReadObject(xr2) as Wcf.Contracts.Data.Presence; var xml3 = @"  PT30M 2013-08-21T10:00:00Z 85 2013-08-21T15:00:00Z "; var xr3 = System.Xml.XmlReader.Create(new System.IO.StringReader(xml3)); var p3 = dcs.ReadObject(xr3) as Wcf.Contracts.Data.Presence; 

三个实例都是不同的。

  | p1 | p2 | p3 Id | default(int) (=0) | 85 | 85 From | 8/21/2013 10:00:00 AM | default(DateTime?) (=null) | 8/21/2013 10:00:00 AM To | 8/21/2013 3:00:00 PM | 8/21/2013 3:00:00 PM | 8/21/2013 3:00:00 PM BreakPeriod | 00:30:00 | default(TimeSpan?) (=null) | 00:30:00 

为什么必须对XML中的元素进行排序? 有人知道DataContractSerializer为什么不正确反序列化?

这是正常的。 datacontract将描述soap消息的xml架构。 DataContractSerializer使用任意字母顺序。 您可以通过指定它来更改顺序:

  [DataMember(Order = 1)] public int MyProperty { get; set; } 

为什么需要指定订单? 我没有时间阅读SOAP RFC,但我认为它正常化。

如果我们考虑一下,它就是速度和尺寸优化的逻辑。 DataContract通过不为null属性值写入任何xml来指定null。 并且假设您有一个具有200个属性的对象,您必须读取所有xml以确定该属性是否为null。 如果你有一个有序元素的xml架构,它会更快。

我希望我所说的有助于更好地理解。