4

I have a question on how to send a custom exception as FaultException. It works when I use a system Exception like ArgumentException, but if I change it to my custom exception "TestException" it fails. I can’t get the configuration for the service reference, when I try to add it.

Works:

[OperationContract]
[FaultContract(typeof(ArgumentException))]
[TransportChannel TestMethod ();


public Void TestMethod()
{
            throw new FaultException<ArgumentException>(new ArgumentException("test"), new FaultReason("test"));
}

Doesn’t work:

[OperationContract]
[FaultContract(typeof(TestException))]
[TransportChannel TestMethod ();


public Void TestMethod()
{
            throw new FaultException<TestException>(new TestException("test"), new FaultReason("test"));
}

My “TestException” looks like this:

[Serializable()]
public class TestException: Exception
{
    public TestException () : base() { }
    public TestException (string message) : base(message) { }
    public TestException (string message, Exception innerException) : base(message, innerException) { }
    public TestException (System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) : base(info, context) { }
}

I guess I have to add a DataContract on the custom object, but I don’t understand why it won’t work like it is, since the ArgumentException works. Can someone enlighten me?

Thanks for help :)

faultEx
  • 43
  • 1
  • 5
  • 1
    Odd. I had a similar problem and got it to work without having to add a `[DataContract]` attribute to my custom exception. I was just missing the constructor that took `SerializationInfo` and `SerializationContext`. Adding that constructor worked for me. – Jeff B Nov 26 '14 at 22:09
  • 1
    @JeffBridgman You probably meant `Serialization.StreamingContext`, not `SerializationContext` – Teejay May 13 '15 at 14:13
  • @Teejay, correct. I referencing [this constructor](https://msdn.microsoft.com/en-us/library/tz6bzkbf(v=vs.110).aspx) but typed the wrong thing. – Jeff B May 13 '15 at 14:16

2 Answers2

7

You do need to mark it with [DataContract] as described at this page: http://msdn.microsoft.com/en-us/library/ms576199.aspx.

I'm assuming (but don't know for sure) that ArgumentException works because it's known on both sides of the wire (assuming you're using .NET on each side). Without declaring your exception as a DataContract, it can't be described and serialized/deserialized correctly by the DataContractSerializer.

NateTheGreat
  • 2,295
  • 13
  • 9
  • 1
    This post at [MSDN](https://social.msdn.microsoft.com/Forums/vstudio/en-US/5fdfc1d7-89f2-4f8b-a491-d9ac2cb0600c/why-can-a-type-not-implement-iserializable-and-have-a-datacontract-attribute?forum=wcf) seems to imply that you can mark it as both `[Serializable]` and [`DataContract`]. I personally got an error when navigating to the `.svc` page in my browser complaining that `Type 'TestException' cannot be ISerializable and have DataContractAttribute attribute`. – Jeff B Nov 26 '14 at 22:18
0

You certainly need to Mark it as DataContract. It is a custom type, which the other side (your client) does not know.

Dipti Mehta
  • 537
  • 3
  • 13