2010-01-11 4 views
10

я следующий класс контракта данных для моей службы WCF:значения по умолчанию WCF Service

[DataContract(Name = "MyClassDTO")] 
public class MyClass 
{ 
    private string name = "Default Name"; 

    [DataMember] 
    public string Name 
    { 
     get { return name; } 
     set { name = value; } 
    } 
} 

Когда я использую Visual Studio Добавить Service Reference функцию для генерации WCF Service Reference генерируемого DataContract выглядит примерно так:

[System.Diagnostics.DebuggerStepThroughAttribute()] 
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.Runtime.Serialization", "3.0.0.0")] 
[System.Runtime.Serialization.DataContractAttribute(Name = "MyClassDTO", Namespace = "xxx")] 
[System.SerializableAttribute()] 
public partial class MyClassDTO : object, System.Runtime.Serialization.IExtensibleDataObject, System.ComponentModel.INotifyPropertyChanged 
{ 

    [System.Runtime.Serialization.OptionalFieldAttribute()] 
    private string NameField; 

    [System.Runtime.Serialization.DataMemberAttribute()] 
    public string Name 
    { 
     get 
     { 
      return this.NameField; 
     } 
     set 
     { 
      if ((object.ReferenceEquals(this.NameField, value) != true)) 
      { 
       this.NameField = value; 
       this.RaisePropertyChanged("Name"); 
      } 
     } 
    } 
} 

Это означает, что значение по умолчанию «по умолчанию название» теряется и происходит следующее:

MyClassDTO mcdto = new MyClassDTO(); 
serviceClient.DoSomething(mcdto); 


[OperationContract] 
void DoSomething(MyClass mc){ 
    mc.Name //<-- == null but I want it to be "Default Name" 
} 

Есть ли способ настроить контракт данных таким образом, чтобы определенное значение по умолчанию «Имя по умолчанию» не потерялось?

Дополнительная информация: Я использую ссылку на службу без повторного использования типов в ссылочных assemblys, например, на стороне клиента класс MyClass DTO генерируется не известно о стороне сервера класса MyClass

ответ

3

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

[DataContract(Name = "MyClassDTO")] 
    public class MyClass 
    { 
     private string name; 

     public MyClass() 
     { 
      Init(); 
     } 

     [DataMember] 
     public string Name 
     { 
      get{ return name; } 
      set 
      { 
       if (!String.IsNullOrEmpty(value)) 
       { 
        name = value; 
       } 
      } 
     } 

     private void Init() 
     { 
      name = "Default Name"; 
     } 

     [System.Runtime.Serialization.OnDeserializing] 
     private void OnDeserializing(StreamingContext ctx) 
     { 
      Init(); 
     } 
    } 
2

Ммм .. Я думал , что есть некоторые вещи, с [DefaultValue(...)], которые будут работать, но, видимо, нет; Я немного смущен, почему вы получаете null, хотя - поскольку вы не сказали об этом по умолчанию, я бы ожидал, что "Default Name" войдет в выход. Если вы имеют код по умолчанию (или ShouldSerialize*/*Specified), то вы можете попробовать:

[DataMember(EmitDefaultValue=true)] 
public string Name { 
    get { return name; } 
    set { name = value; } 
} 

Но опять-таки - я не совсем уверен, почему вы видите на null в первую очередь.

Я только что проверил это с чем-то на основе шаблона WCF в VS2008, и она отлично работает:

using (var client = new Service1Client()) { 
    var result = client.GetDataUsingDataContract(); 
    Console.Write(result.Name); // "Default Name" 
} 
+0

Да с сервером направления -> клиент работает отлично. но в направлении клиент -> сервер он не работает. Обратите внимание, что на клиентском сайте класс DataContract MyClassDTO является сгенерированным, который используется только на стороне клиента.Клиент не знает MyClass, и серверная сторона не знает о классе MyClassDTO – Fabiano

2

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

Кроме того, вы ничего не сделали, чтобы сообщить WCF, что вы имеете в виду значение по умолчанию, поэтому даже если есть способ сообщить о своем намерении клиенту, факт заключается в том, что вы не сообщаете о своих намерениях ,

+0

. Это потому, что я ищу способ сообщить об этом :-) Но кажется (как вы сказали), что нет способа сделать это Это. – Fabiano

1

Во время десериализации логика «set» вашего свойства будет выполнена, поэтому вы можете проверить там нулевое значение и установить, что вы хотите по умолчанию в этой точке.

+0

это, кажется, единственный способ достичь моей цели. но во время десериализации не вызывается конструктор и объект не инициализируется, поэтому вы должны использовать константные переменные – Fabiano

Смежные вопросы