Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

DataContract and inheritance?

Tags:

c#

wcf

How to use DataContract with inheritance? Will code below work?

[DataContract] public class ConsoleData {     [DataMember]     public String Description { get; set; }  }  [DataContract] public class SomeData : ConsoleData {      [DataMember]     public int Volume { get; set; }     ...... 
like image 958
Oleg Vazhnev Avatar asked Dec 18 '11 21:12

Oleg Vazhnev


People also ask

What does DataContract mean?

It is used to get or set the order of serialization and deserialization of a member. ISRequired. It instructs the serialization engine that member must be present while reading or deserializing. Name. It gets or sets the DataMember name.

Is DataContract mandatory in WCF?

No, the DataContractAttribute is not required - WCF will infer serialization rules.

What does DataMember mean?

Data Member are the fields or properties of your Data Contract class. You must specify [DataMember] attribute on the property or the field of your Data Contract class to identify it as a Data Member. DataContractSerializer will serialize only those members, which are annotated by [DataMemeber] attribute.

What is used if you expect the service to accept and return inherited types?

If you expect the service to accept and return an inherited type then we use the knowntype attribute.


1 Answers

Yes, that would work.

The DataContractAttribute has Inherited set to false, so it is necessary to apply the attribute to both the child class and the parent class (as you have done in the question).


You would need to use the KnownType attribute if you want to use your data contracts with polymorphism.

For example

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

If you invoked the method like so:

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

Then the deserializer on the service end will not know that it's an instance of SomeData, just an instance of ConsoleData which it was expecting. The way to fix this is to register the SomeData class as a known type of the ConsoleData.

[DataContract] [KnownType(typeof(SomeData))] public class ConsoleData {     [DataMember]     public String Description { get; set; }  }  [DataContract] public class SomeData : ConsoleData {      [DataMember]     public int Volume { get; set; }     ...... 
like image 54
Andrew Shepherd Avatar answered Oct 04 '22 07:10

Andrew Shepherd