We have an abstract class that is the base for a number of different requests we send over a WCF service. It's an ugly heinous hack that every time we add a new request we have to remember to add the [KnownType]
attribute to this base class.
Is there a way to tell the DataContractSerializer
to treat ALL derivations of this abstract type as a KnownType
?
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.
Yes, You can inherit an abstract class from another abstract class.
If you expect the service to accept and return an inherited type then we use the knowntype attribute.
I had the same problem in a WCF service and did the following "less heinous" hack to work around the known type limitation. I'm outlining just for the sake of showing alternate options, it's up to you to decide if it's better or not.
At service startup, load via reflection the types you want to expose. E.g. if all your WCF-exposed entities derive from a common abstract base (or more), load all types from the assembly they're supposed to be located into. Cache these types statically for performance reasons.
Create a static method that returns the said cached types, with the following signature:
public static IEnumerable<Type> GetKnownTypes(ICustomAttributeProvider provider)
Mark the WCF interface with the following attribute
[ServiceKnownType("GetKnownTypes", typeof(StaticClassThatCachesTypes))]
This should give you automatic exposing of all types that are or will be derived from the base class(es) of your choice, as long as the future developer(s) place them in the correct assembly.
Another option in addition to the one given by Dan C. is to switch to the NetDataContractSerializer - it does not require known type declarations, since it is tightly coupled to the exact contract implementation, so you'll need to share the assembly which contains the types between the client and the server - and you'll definitely lose interoperability in this scenario. There are a few posts about doing that (I've seen this one pop up in google/bing results often).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With