Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In WCF, can data contract classes inherit from one another?

Tags:

In a WCF service, I have two classes with the [DataContract] attribute. One of these classes has an "is-a" relationship with the other - so class B can inherit from class A. However, when I configure inheritance between these two classes, both denoted with a [DataContract] attribute, the metadata fails to load when testing the services.

Is this possible in WCF? Am I missing another attribute?

[DataContract] public class A {             [DataMember]     public MyCustomType AValue1{ get; set; }      [DataMember]     public MyCustomType AValue2 { get; set; } }  [DataContract] public class B: A {           [DataMember]    public double BValue1{ get; set; }     [DataMember]    public double BValue2 { get; set; } } 

NOTE: The custom types are also defined using data contracts.

UPDATE: Below is the error:

Error: Cannot obtain Metadata from http://localhost:8002/GISDataServices/mex If this is a Windows (R) Communication Foundation service to which you have access, please check that you have enabled metadata publishing at the specified address. For help enabling metadata publishing, please refer to the MSDN documentation at http://go.microsoft.com/fwlink/?LinkId=65455.WS-Metadata Exchange Error URI: http://localhost:8002/GISDataServices/mex Metadata contains a reference that cannot be resolved: 'http://localhost:8002/GISDataServices/mex'. Receivera:InternalServiceFaultThe server was unable to process the request due to an internal error. For more information about the error, either turn on IncludeExceptionDetailInFaults (either from ServiceBehaviorAttribute or from the <serviceDebug> configuration behavior) on the server in order to send the exception information back to the client, or turn on tracing as per the Microsoft .NET Framework 3.0 SDK documentation and inspect the server trace logs.HTTP GET Error URI: http://localhost:8002/GISDataServices/mex There was an error downloading 'http://localhost:8002/GISDataServices/mex'. The request failed with HTTP status 400: Bad Request.

UPDATE 2: See my answer below.

like image 676
Jordan Parmer Avatar asked Feb 04 '09 15:02

Jordan Parmer


People also ask

Which contract in WCF defines the type of data passed from service to client?

A Data Contract defines what data type to be passed to or from the client. In the WCF service, the Data Contract takes a major role for serialization and deserialization. There are two types of Data Contracts. This contract declares and defines the class to be serialized for the client to access.

Which attribute is used for defining data contracts in WCF?

The DataContract attribute is used to mention the custom class as data contract and the DataMember attribute is used to mention the data member as a member of the data contract. We can use this for both the data member and properties of the class.

Which WCF attribute specifies that the data type can be used by client application?

According to MSDN the KnownTypeAttribute class allows you to specify, in advance, the types that should be included for consideration during deserialization. The WCF service generally accepts and returns the base type. If you expect the service to accept and return an inherited type then we use the knowntype attribute.

What is the KnownType attribute in WCF?

The [KnownType] attribute informs the WCF service that "it is ok" to receive this Admin type because it is a subclass of the awaited UserAccount type. It is especially important when the Admin subclass has more properties, like a public string AdminEmail { get;set; } . This property will be sent by the client too.


2 Answers

Yes, but you need to decorate the base class with the [KnownTypeAttribute] constructing it with the derived class's type. For instance:

[DataContract] [KnownType(typeof(B))] public class A {    [DataMember]    public string Value { get; set; } }  [DataContract] public class B : A {    [DataMember]    public string OtherValue { get; set; } } 
like image 149
David Morton Avatar answered Sep 25 '22 19:09

David Morton


Okay, I figured out the question. The answer is...I'm an idiot. It had nothing to do with inheritance. In the base class, I had a data contract member without a 'set' property clause - only a 'get'. Doh!!! Putting in a 'set' clause made it work like a charm.

Sorry for the confusion.

like image 36
Jordan Parmer Avatar answered Sep 21 '22 19:09

Jordan Parmer