【问题标题】:Data member default values, how to figure out whether something was really sent?数据成员默认值,如何判断是否真的发送了什么?
【发布时间】:2012-01-24 20:17:24
【问题描述】:

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

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

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

Microsoft 的简短回答是“由接收端点正确解释缺失的元素”。

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

有人能解释一下这是什么意思吗?

谢谢

【问题讨论】:

标签: wcf datamember


【解决方案1】:

如果您将数据成员定义为属性,您可以使用是否调用 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);
    }
}

【讨论】:

  • 我今天尝试了这个解决方案,我只能说它就像一个魅力!这正是我想要的:)
  • 这太棒了。谢谢!
猜你喜欢
  • 2014-09-02
  • 2012-08-27
  • 2016-04-27
  • 2011-02-06
  • 1970-01-01
  • 2012-01-05
  • 2012-10-06
  • 2013-01-17
  • 1970-01-01
相关资源
最近更新 更多