2010-01-11 15 views
10

He siguientes clases contrato de datos para mi servicio WCF:valores por defecto servicio WCF

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

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

Cuando uso de Visual Studio Añadir Servicio de referencia de funciones para generar una referencia de servicio WCF la generada DataContract se ve algo como esto:

[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"); 
      } 
     } 
    } 
} 

Eso quiere decir, el valor predeterminado "Nombre predeterminado" se pierde y el comportamiento siguiente:

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


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

¿Existe alguna manera de configurar el contrato de datos de esa manera, que el valor predeterminado definido "Nombre predeterminado" no se pierda?

información adicional: I utilizar una referencia de servicio sin reutilización de tipos en assemblys referenciados, por ejemplo, en el lado del cliente se genera la clase MiClase DTO una no es consciente de la clase MyClass lado del servidor

Respuesta

3

La única solución posible (pero fea y por lo tanto no muy satisfactoria) que encontré hasta ahora es usar el atributo OnDeserializing para establecer los valores predeterminados al inicio de la deserialización y usar el setter de un campo para determinar si el valor comunicado realmente debería ser establecido.

[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

Hmmm .. Yo pensé que había algunas cosas con [DefaultValue(...)] que funcionarían, pero al parecer no; Sin embargo, estoy un poco confundido sobre por qué obtienes null, ya que no le has contado ningún defecto esperaría que "Default Name" ingresara en la salida. Si usted tiene algún código por defecto (o una ShouldSerialize*/*Specified) entonces usted podría intentar:

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

Pero una vez más - no estoy del todo seguro de por qué usted está viendo un null en el primer lugar.

he acabo de probar esto con algo basado en la plantilla de WCF en VS2008, y funciona bien:

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

Sí, con el servidor de dirección -> cliente esto funciona bien. pero en la dirección cliente -> servidor no funciona. Tenga en cuenta que en el sitio del cliente, la clase DataContract MyClassDTO es una generación que solo se utiliza en el lado del cliente.El cliente no conoce MyClass y el servidor no tiene conocimiento de la clase MyClassDTO – Fabiano

2

No creo que el esquema XML permite la descripción de un valor por defecto de un elemento . Esto significa que, en lo que respecta a un cliente de su servicio, es sin valor predeterminado.

Además de eso, no ha hecho nada para decirle a WCF que quiere tener un valor predeterminado, por lo que incluso si hubiera una forma de comunicar su intención a un cliente, el hecho es que no está comunicando su intención .

+0

Eso es porque estoy buscando una forma de comunicarlo :-) Pero parece (como dijiste) que no hay forma de hacerlo eso. – Fabiano

1

Durante la deserialización, se ejecutará la lógica 'set' de su propiedad, por lo que podría verificar allí nulo y establecerse en el valor que desee en ese punto.

+0

esto parece ser la única manera de lograr mi objetivo. pero durante la deserialización no se llama a ningún constructor y el objeto no se inicializa, por lo tanto, debe usar variables const – Fabiano

Cuestiones relacionadas