2011-12-18 19 views
20

¿Cómo usar DataContract con herencia? ¿Funcionará el código a continuación?DataContract y herencia?

[DataContract] 
public class ConsoleData 
{ 
    [DataMember] 
    public String Description { get; set; } 

} 

[DataContract] 
public class SomeData : ConsoleData 
{ 

    [DataMember] 
    public int Volume { get; set; } 
    ...... 
+0

Sí. ¿Qué estás tratando de hacer con esos dos contratos de datos? –

Respuesta

34

Sí, eso funcionaría.

DataContractAttribute tiene Inherited establecido en falso, por lo que es necesario aplicar el atributo a la clase secundaria y a la clase principal (como lo ha hecho en la pregunta).


Necesitará utilizar el atributo KnownType si desea utilizar sus contratos de datos con polimorfismo.

Por ejemplo

[ServiceContract] 
interface MyWcfContract 
{ 
     [OperationContract] 
     HandleData(ConsoleData contractData); 
} 

Si ha invocado el método de esta manera:

SomeData someData = new SomeData { Description = "Test", Volume = 30 }; 
// The method is expecting a ConsoleData instance, 
// I'm passing a SomeData instance instead 
myWcfProxy.HandleData(someData); 

Entonces el deserializer en el extremo servicio no sabrá que se trata de una instancia de SomeData, sólo una instancia de ConsoleData que estaba esperando. La forma de solucionar esto es registrar la clase SomeData como un tipo conocido del ConsoleData.

+0

gracias, realmente ayudó y solucionó mis problemas – javapowered

+0

@Andrew. Me estoy poniendo nervioso con estos temas por mucho tiempo. ¿Es posible tener en '[OperationContract] HandleData (Base base);' y enviar desde SoapUI algunos objetos diestros de 'Base'? Y luego si C# tendrá en cuenta el hecho de que en 'base' es instancia de retención de alguna subclase, por lo que también invoca métodos adecuados (polimorfismo, etc.) –

+0

Hubo un error de sintaxis menor en [KnownType (typeof (SomeData)] ], gracias por la útil publicación. – Shanjee

2

Tendrá que utilizar el atributo KnownType si está utilizando el XmlSerializerFormat para su ServiceContract:

[DataContract] 
public class ConsoleData 
{ 
    [DataMember] 
    public String Description { get; set; } 
} 

[DataContract, KnownType(typeof(ConsoleData))] 
public class SomeData : ConsoleData 
{ 
    [DataMember] 
    public int Volume { get; set; } 
} 
+0

¿qué no funcionará sin 'KnownType'? Probé el código como lo escribí en la descripción y parece que funciona – javapowered

+1

. Lo cuestiono. Tiene sentido poner KnownType (typeof (SomeData)) en la clase base (ConsoleData), lo que le permite pasar una instancia hija a un método que espera una instancia base. Pero no creo que deba ponerlo en la instancia hija. –

+0

@javapowered: solo tenga cuidado si decide no usar el atributo KnownType porque hay casos especiales en los que es necesario. Un ejemplo de esto es si expone SomeData como propiedad de otro DataContract. –