When is it appropriate to use the KnownType attribute?
After reading the MSDN reference, I still have questions about when to use the KnownType attribute. I understand that the attribute communicates type information to the serializer, but when is this needed? Is it appropriate when the class being serialized has references of a base class type, and there are up-cast derivative classes that could be set to those references?
Moreover, are there any drawbacks to overusing the attribute? For instance, in the previous example, if the serialized class was marked with KnownType(baseClass) even though there was an explicit reference to that type?
Solution 1:
[KnownType]
is needed to tell it about subtypes. The disadvantage of not using it is that the following won't work:
[DataContract]
class Foo {}
[DataContract]
class Bar : Foo {}
with a method on the WCF interface that returns:
public Foo GetFoo() { return new Bar(); }
Without the attribute, the serializer (especially for mex/proxy-generated types) won't know about Bar
, and it will fail. With the attribute:
[DataContract, KnownType(typeof(Bar))]
class Foo {}
it will work. This only applies to DataContractSerializer
- with NetDataContractSerializer
you get the type data in a different way.
Solution 2:
The KnownType attribute is necessary when you are serializing non-concrete types such as interfaces or base classes. The WCF serializer must know about all possible implementations of the interface or inherited class. Any implementations that it doesn't know about will cause a serialization exception.
One possable usage can be found in this SO question
Solution 3:
If you're using XSD "inheritance" in your schema.
You've got it backwards; the KnownTypeAttribute is applied to the base class and names all of the derived classes that might be passed as a reference to the base.
For instance:
...
[KnownType(typeof(POBoxAddress))]
[KnownType(typeof(StreetAddress))]
[KnownType(typeof(SingleLineAddress))]
[KnownType(typeof(ParsedAddress))]
public abstract class AddressBase
{
...
}