2

デフォルトでは、WCFは欠落している要素をnull、0、falseなどのデフォルト値に逆シリアル化します。このアプローチの問題は、それが数値0のような基本タイプである場合、それが外部システムによって送信された実際の値を意味するのか、WCFによって生成されたデフォルト値を意味するのかわからないことです。

だから私の質問は:デフォルト値が「私は何も送信しなかった」を意味するかどうかを実行時に見つけることは可能ですか?

今回は外部システムが特定の要素を送信しなかった(データの破損)という理由だけで、データベース内の既存のデータをデフォルト値で更新および上書きできないため、これは非常に重要です。

Microsoftの簡単な答えは、「欠落している要素を適切に解釈するのは受信側のエンドポイント次第です」です。

データメンバーのデフォルト値 http://msdn.microsoft.com/en-us/library/aa347792.aspx

誰かがそれが何を意味するのかを明確にしてくれませんか?

ありがとう

4

1 に答える 1

3

データ メンバーをプロパティとして定義すると、setter が呼び出されたかどうかを使用して、何らかの値が送信されたかどうかを判断できます。以下のコードは、フィールドを逆シリアル化したかどうかを認識している 1 つのデータ コントラクトを示しています。

public class Post_51ca1ead_2f0a_4912_a451_374daab0101b
{
    [DataContract(Name = "Person", Namespace = "")]
    public class Person
    {
        string name;
        int age;
        bool nameWasSent;
        bool ageWasSent;

        [DataMember]
        public string Name
        {
            get
            {
                return this.name;
            }

            set
            {
                this.nameWasSent = true;
                this.name = value;
            }
        }

        [DataMember]
        public int Age
        {
            get
            {
                return this.age;
            }

            set
            {
                this.ageWasSent = true;
                this.age = value;
            }
        }

        [OnDeserializing]
        void OnDeserializing(StreamingContext ctx)
        {
            this.ageWasSent = false;
            this.nameWasSent = false;
        }

        public override string ToString()
        {
            return string.Format("Person[Name={0},Age={1}]",
                nameWasSent ? name : "UNSPECIFIED",
                ageWasSent ? age.ToString() : "UNSPECIFIED");
        }
    }

    public static void Test()
    {
        MemoryStream ms = new MemoryStream();
        DataContractSerializer dcs = new DataContractSerializer(typeof(Person));
        dcs.WriteObject(ms, new Person { Name = "John", Age = 30 });
        Console.WriteLine(Encoding.UTF8.GetString(ms.ToArray()));

        string noAge = "<Person><Name>John</Name></Person>";
        ms = new MemoryStream(Encoding.UTF8.GetBytes(noAge));
        object p = dcs.ReadObject(ms);
        Console.WriteLine("No age: {0}", p);

        string noName = "<Person><Age>45</Age></Person>";
        ms = new MemoryStream(Encoding.UTF8.GetBytes(noName));
        p = dcs.ReadObject(ms);
        Console.WriteLine("No name: {0}", p);
    }
}
于 2012-01-24T21:02:30.933 に答える