views:

279

answers:

1

Hi,

I'm trying to throw my own custom exception inside a FaultException from my WCF service and catch it in my WCF client. On the client side, however, the exception is caught as a non-generic FaultException and the details of my custom exception are lost.

My custom exception is:

[Serializable] public class MyCustomException : ApplicationException 
{ ... }

Here's how I throw it:

throw new FaultException<MyCustomException>(new MyCustomException("foo bar!"));

(Note that I do have a [FaultContract(typeof(MyCustomException))] placed over my method in the interface)

And here's how I try to catch it in my client:

...
catch (FaultException<MyCustomException> mcex)
{
    Console.WriteLine(mcex); 
}
 catch (FaultException fex) 
{
    Console.WriteLine(fex); 
}

My goal is for the exception to be caught in the first catch clause above, but it ends up caught in the second catch clause.

The curious thing is that if I replace MyCustomException with ApplicationException then indeed FaultException is properly caught.

I'm guessing the problem is that MyCustomException is serialized a Serializable (and not via the DataContractSerializer) and that maybe I'm missing some additional directive to WCF. Something in the line of a ServiceKnownType attribute? (Though I tried that, to no avail).

+2  A: 

Yes, you won't be able to catch the generic FaultException until you specify that type as a fault contract in your service contract:

[ServiceContract]
interface IYourService
{
   [OperationContract]
   [FaultContract(typeof(MyCustomException))]
   SomeReturnValue YourMethodCall(SomeInputValue input);
}

Only once you do this, then you can catch and handle the specific, generically typed FaultException in your client side code.

See the MSDN docs on FaultException<T> this blog post for some more background and good info on WCF error handling.

Also, I would personally always decorate my fault contract classes with a [DataContract] attribute (and all the members I want to have serialized with [DataMember]):

[Serializable] 
[DataContract]
public class MyCustomException : ApplicationException 
{ ... }
marc_s
Thanks for helping but as I've mentioned originally, I already have the FaultContract attribute properly set on the throwing method in the ServiceContract and this did not solve the issue.Also, it is not possible AFAIK to decorate Exceptions in .net with [DataContract], as Exceptions always implement ISerializable and these two serialization mechanisms conflict. At least whenever I tried this today, I ended up with a very explicit error indicating it. More info here: http://tinyurl.com/yd634sa and here: http://tinyurl.com/y8jgf42 :)
urig
Yes, typically, since SOAP faults are designed for interoperability with non .NET clients, you wouldn't just use standard .NET exceptions as your details, but custom classes which I'd decorate with [DataContract] and [DataMember]
marc_s