4

次のデータ契約があります。

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 から指定された値ではなく、デフォルト値を取得しました。Presenceのプロパティを表す XML の要素は、アルファベット順に並べる必要があることがわかりました。

たとえば、このコード スニペットでは

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;

3 つのインスタンスはすべて異なります。

            | 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そうでなければ正しく逆シリアル化されない理由を誰かが知っていますか?

4

1 に答える 1

3

それは正常です。datacontract は、soap メッセージの xml スキーマを記述します。DataContractSerializer は任意のアルファベット順を使用します。指定することで順序を変更できます:

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

なぜ順序を指定する必要があるのですか? SOAP RFC を読む時間はありませんが、標準化されていると思います。

考えてみれば、それは速度とサイズの最適化のためのロジックです。DataContract は、null プロパティ値の xml を記述しないことで null を指定します。また、200 個のプロパティを持つオブジェクトがある場合、すべての xml を読み取ってプロパティが null かどうかを判断する必要があるとします。要素を順序付けた xml スキーマがある場合は、より高速です。

私が言わなければならなかったことが、より良い理解に貢献したことを願っています。

于 2013-09-03T13:05:52.177 に答える