数据成员默认值,如何判断是否真的发送了什么?

时间:2012-01-24 20:17:25

标签: wcf datamember

默认情况下,WCF将缺少的元素反序列化为默认值,如null,0或false。这种方法的问题在于,如果它是类似0的基本类型,我不确定它是否意味着外部系统发送的实际值或WCF生成的默认值。

所以我的问题是:是否有可能在运行时发现默认值是否意味着“我没有发送任何内容”。

这一点至关重要,因为我们无法使用默认值更新和覆盖数据库中的现有数据,因为外部系统此次没有发送特定元素(数据损坏)。

微软的简短回答是“接收端点需要正确解释丢失的元素。”

数据成员默认值 http://msdn.microsoft.com/en-us/library/aa347792.aspx

有人可以澄清一下这意味着什么吗?

由于

1 个答案:

答案 0 :(得分:3)

如果将数据成员定义为属性,则可以使用是否调用setter来决定是否发送了某个值。下面的代码显示了一个数据协定,它知道它是否对其字段进行了反序列化。

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