As this seems a rather popular topic, I’ve decided to rewrite this post in a more “reader friendly” format. Here goes…
I was really under the impression that WCF allowed "any" type to be used as FaultContract<T>, as long as the type was marked with the [Serializable]-attribute. Surprise-surprise - that is not the case!
If you do not want to declare a completely custom type using the [DataContract] attribute on your own class, but instead provide an Exception-derived type (which is quite common in .NET-.NET scenarios where no interoperability is required), you need to take into account a couple of things. In addition - the "exception based" programming model is more in sync with the general .NET paradigm and thereby easier to handle by a programmer.
First of all - the type to be used as <T> in the FaultContract<T>, is to inherit from CommunicationException (not System.Exception); or so the documentation says. In reality System.Exception will actually do, but better to stay current with the documentation. Next is the really important part - Provide a protected constructor allowing for the serialization process taking SerializationInfo and StreamingContext as arguments:
[Serializable]SERVICE: When declaring a type like the above, it will be (re)thrown at the Client-side (by the proxy) correctly when declared in the ServiceContract like this using the FaultContract(type) as seen below:
public class MyCustomException : CommunicationException
public MyCustomException(string msg) : base(msg)
protected MyCustomException(SerializationInfo info, StreamingContext ctxt) : base(info, ctxt)
/// My service contract
public interface IMyService
/// Prints the string.
/// <param name="msg">The MSG.</param>
void PrintString(string msg);
The service implementation throwing the exception (MyCustomException) looks like this:
public class MyService : IMyService
#region IMyService Members
public void PrintString(string msg)
throw new FaultException<MyCustomException>(new MyCustomException("Input was null"));
//to stuff with input, otherwise...
CLIENT: Throwing this exception-derived type in the service implementation will propagate to the Client just fine and can be caught like this in the client:
Console.WriteLine("The proper exception caught");
Console.WriteLine("The INCORRECT exception caught");
2011.03.16: Update: To be able to convey your own custom data as well, see this post:
Technorati Tags: WCF