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

时间:2013-08-27 10:59:54

标签: c# xml serialization datacontractserializer alphabetical

我有以下数据合同:

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 = @"<?xml version=""1.0"" encoding=""utf-16""?>
<Presence xmlns:i=""http://www.w3.org/2001/XMLSchema-instance"" xmlns=""http://schemas.datacontract.org/2004/07/Wcf.Contracts.Data"">
  <BreakPeriod>PT30M</BreakPeriod>
  <From>2013-08-21T10:00:00Z</From>
  <To>2013-08-21T15:00:00Z</To>
  <Id>85</Id>
</Presence>";
var xr1 = System.Xml.XmlReader.Create(new System.IO.StringReader(xml1));
var p1 = dcs.ReadObject(xr1) as Wcf.Contracts.Data.Presence;

var xml2 = @"<?xml version=""1.0"" encoding=""utf-16""?>
<Presence xmlns:i=""http://www.w3.org/2001/XMLSchema-instance"" xmlns=""http://schemas.datacontract.org/2004/07/Wcf.Contracts.Data"">
  <Id>85</Id>
  <From>2013-08-21T10:00:00Z</From>
  <To>2013-08-21T15:00:00Z</To>
  <BreakPeriod>PT30M</BreakPeriod>
</Presence>";
var xr2 = System.Xml.XmlReader.Create(new System.IO.StringReader(xml2));
var p2 = dcs.ReadObject(xr2) as Wcf.Contracts.Data.Presence;

var xml3 = @"<?xml version=""1.0"" encoding=""utf-16""?>
<Presence xmlns:i=""http://www.w3.org/2001/XMLSchema-instance"" xmlns=""http://schemas.datacontract.org/2004/07/Wcf.Contracts.Data"">
  <BreakPeriod>PT30M</BreakPeriod>
  <From>2013-08-21T10:00:00Z</From>
  <Id>85</Id>
  <To>2013-08-21T15:00:00Z</To>
</Presence>";

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不能正确反序列化吗?

1 个答案:

答案 0 :(得分:2)

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

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

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

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

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