I've been designing web services for quite a while now but never had to expose a 'complicated' WCF service until recently. I was baffled at the apparent lack of "proper support" in WCF for abstract types. Sure - you can USE them - sure you can get them to 'work'... you just don't end up with what you WANT...
The first problem is that if you generate code from a wsdl with an abstract type you get vastly different code because it falls back to the xmlserializer and not the DataContractSerializer. This is obviously a bit less than desirable... I'd like to use the fancy new faster serializer please thank you... (and all that comes along with Service/DataContract)
on the flip side - if you start with code first and expose a properly attributed abstract wcf class as a web service the exposed wsdl does NOT contain the abstract="true" attribute making the "abstract class" technically concrete... This is not what I want of course...
I've got a workaround but it involves a crazy amount of 'hackery' where I create the wsdl/xsd contract first, remove any abstract="true" (oh - let's not mention that I can't use attributes in the xsd shall we) and then svcuitl the result... But now I'm left with a c# api that has a CONCRETE abstract class and I then need to go modify that to ADD the abstract keyword... This 'works' but it's a huge pita - and not easily 'scriptable'...
This is all just whacked! I'm hoping someone can explain to me precisely 'why' this is... I welcome answers that don't cite "solid" resources but I'm really waiting for the person to tell me - with proper documentation (like preferably from good ol Don Box himself) why exactly this is... Cause I just don't get it...
Thanks all - if anyone would like more details - please let me know!
UPDATED FOR ADDITION OF A SAMPLE REQUEST - starting with c# [ServiceContract] public interface IShapeTest { [OperationContract] AbsShape EchoShape(AbsShape shape); }
public class ShapeTestImpl : IShapeTest
{
public AbsShape EchoShape(AbsShape shape)
{
return shape;
}
}
[KnownType(typeof(Square))]
public abstract class AbsShape
{
[DataMember]
public int numSides;
}
public class Square : AbsShape
{
public Square() : base()
{
numSides = 4;//set the numSides to 'prove' it works
}
}
EXPECTED TYPE:
<xs:complexType name="AbsShape" abstract="true"> <!--NOTE abstract="true"-->
<xs:sequence>
<xs:element minOccurs="0" name="numSides" type="xs:int"/>
</xs:sequence>
</xs:complexType>
ACTUAL EMITTED TYPE:
<xs:complexType name="AbsShape"> <!--NOTE the lack of abstract="true"-->
<xs:sequence>
<xs:element minOccurs="0" name="numSides" type="xs:int"/>
</xs:sequence>
</xs:complexType>