2

默认情况下,WCF 将丢失的元素反序列化为默认值,如 null、0 或 false。这种方法的问题在于,如果它是像数字 0 这样的基本类型,我不确定它是指外部系统发送的实际值还是 WCF 生成的默认值。

所以我的问题是:是否可以在运行时找出默认值是否意味着“我没有发送任何东西”。

这是至关重要的,因为我们不能仅仅因为外部系统这次没有发送特定元素(数据损坏)而用默认值更新和覆盖数据库中的现有数据。

微软的简短回答是“由接收端点适当解释缺失的元素。”

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

有人可以澄清这应该是什么意思吗?

谢谢

4

1 回答 1

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);
    }
}
于 2012-01-24T21:02:30.933 回答