Why needs DataContractSerializer alphabetically sorted XML?

梦想与她 提交于 2019-12-06 09:46:36

问题


I have following data contract:

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; }
  }
}

Serializing an instance of Presence to XML and deserializing the same XML back to an instance of Presence works well. But deserializing a string variable which represents a serialized Presence object gave me strange behaviors. Some properties got default values rather than the specified values from the XML. I have found out that the elements in the XML which represent the properties of Presence must be alphabetically ordered.

For example in this snippet of code

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;

the three instances are all different.

            | 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

Why do the elements in the XML have to be sorted? Does anybody know why the DataContractSerializer otherwise does not deserialize correctly?


回答1:


It's normal. The datacontract will describe the xml schema for the soap message. The DataContractSerializer use arbitrarily alphabetic order. You could change the order by specifying it :

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

Why does it necessary to specify the order? I don't have time to read the SOAP RFC but I think it's normalize.

And if we think about it, it's logic for speed and size optimization. DataContract specify the null by not writing any xml for null property value. And imagine if you have an object with 200 properties you have to read all the xml to determine if the property is null. If you have an xml schema that ordered element it's faster.

I hope that what I have had to say has contributed to a better understanding.



来源:https://stackoverflow.com/questions/18463575/why-needs-datacontractserializer-alphabetically-sorted-xml

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!