Значения элемента данных по умолчанию, как выяснить, действительно ли что-то было отправлено? - PullRequest
2 голосов
/ 25 января 2012

По умолчанию WCF десериализует отсутствующие элементы в значения по умолчанию, такие как null, 0 или false. Проблема этого подхода в том, что если это базовый тип, такой как число 0, я не уверен, означает ли это реальное значение, отправленное внешней системой, или значение по умолчанию, сгенерированное WCF.

Итак, мой вопрос: возможно ли во время выполнения выяснить, означает ли значение по умолчанию «Я ничего не отправлял».

Это крайне важно, потому что мы не можем обновить и перезаписать существующие данные в базе данных значениями по умолчанию только потому, что внешняя система на этот раз не отправила определенный элемент (повреждение данных).

Краткий ответ Microsoft: «Получающая конечная точка должна правильно интерпретировать отсутствующий элемент».

Значения элемента данных по умолчанию http://msdn.microsoft.com/en-us/library/aa347792.aspx

Может кто-нибудь уточнить, что это должно означать?

Спасибо

1 Ответ

3 голосов
/ 25 января 2012

Если вы определяете свои элементы данных как свойства, вы можете использовать, вызван ли сеттер или нет, чтобы решить, было ли отправлено какое-то значение. Код ниже показывает один контракт данных, который знает, десериализовал ли он свои поля.

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