2012-01-24 1 views
2

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

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

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

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

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

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

Благодаря

+2

Вы можете использовать OnDeserializedAttribute или OnDeserializingAttribute http://msdn.microsoft.com/en-us/library/system.runtime.serialization.ondeserializedattribute.aspx или http://msdn.microsoft.com/en- us/library/system.runtime.serialization.ondeserializingattribute.aspx –

+0

Как насчет использования элементов с возможностью сбрасывания данных? http://stackoverflow.com/questions/2426892/wcf-datacontract-does-it-support-nullable-data-member В принципе, я хотел бы иметь какие-то нулевые проверки перед сохранением полей в базе данных. Может ли WCF десериализовать отсутствующие элементы в значениях с нулевыми значениями? – user405723

ответ

3

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

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

Спасибо! Я попробую это завтра на работе. – user405723

+0

Я пробовал это решение сегодня, и все, что я могу сказать, это то, что он работал как шарм! Это было именно то, что я искал :) – user405723

+0

Это просто потрясающе. Благодаря! –