Adding IPrincipal to the list of known types in WCF

WCF has a concept called Known Types, which lets WCF handle subclasses and interface implementations passed to services. Normally you can just whack a KnownTypeAttribute on your DataContract and you’re good to go:

public class Employee { ... }

In the example above, the service will be able to use the Manager subclass anywhere it expects an Employee.

This doesn’t help much when you want to use non-DataContract types like IPrincipal. Trying to pass a GenericPrincipal to a service operation that expects an IPrincipal gives you an error message like this (line breaks added for slightly improved legibility):

Type 'System.Security.Principal.GenericPrincipal' with data contract name 'GenericPrincipal:' is not expected. 
Add any types not known statically to the list of known types - 
for example, by using the KnownTypeAttribute attribute or by adding them to the list of known types passed to DataContractSerializer.

One solution is to decorate your service contract with a ServiceKnownTypeAttribute:

public interface ISomeService {
  String DoSomethingWith(IPrincipal principal);

While I don’t necessarily recommend exposing IPrincipal through your service, the technique is worth knowing about. Most of the search results I got mentioned KnownTypeAttribute and not ServiceKnownTypeAttribute.

Thanks to Steven Cheng who answered this question in his response to this post. Steven also provided a link to Bennie Haelen’s fantastic post on Handling Data Contract Object Hierarchies in WCF, which covers more than you could ever want to know about this stuff :-).