I'm banging my head against the wall on this issue, and have checked all the other similar questions on SO to no avail. I've got a simple FaultException that I'm throwing on a WCF server and catching on the client.
Here's the contract:
[ServiceContract]
public interface MyContract
{
[OperationContract, FaultContract(typeof(TDetail))]
void ThrowException();
}
[DataContract]
public class TDetail
{
public TDetail(string test) {
Test = test;
}
[DataMember]
public string Test { get; set; }
}
The server code throwing the exception:
throw new FaultException<TDetail>(new TDetail("Test"), "My test fault.");
The XML the client receives (courtesy of Fiddler):
I'm a bit suspicious of this, since my class is named "TDetail", not "Sender".
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Body>
<s:Fault>
<faultcode>s:Client</faultcode>
<faultstring xml:lang="en-US">My test fault.</faultstring>
<detail>
<Sender xmlns:a="http://schemas.datacontract.org/2004/07/Sample.Namespace" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<a:Test>MyTest</a:Test>
</Sender>
</detail>
</s:Fault>
</s:Body>
</s:Envelope>
The client code getting the exception:
catch (FaultException<TDetail> ex)
{
// I expect this
}
catch (FaultException ex)
{
// But get this D:
}
And the exception the client receives:
System.ServiceModel.FaultException was caught
HResult=-2146233087
Message=My test fault.
Source=mscorlib
StackTrace:
Server stack trace:
at System.ServiceModel.Channels.ServiceChannel.HandleReply(ProxyOperationRuntime operation, ProxyRpc& rpc)
at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs, TimeSpan timeout)
at System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage methodCall, ProxyOperationRuntime operation)
at System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage message)
Exception rethrown at [0]:
at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg)
at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type)
at Sample.Namespace.ThrowException()
InnerException:
For the life of me I cannot figure out why TDetail is apparently being thrown out by the client. I'm certain that both the client and the server are referencing the same class (I literally copy-pasted the DLL into the right folders), and my implementation is hardly complex. This was even working fine last year, and I can't find any substantial code changes made since then.
Any help? :(
On why my question isn't the same as the potential duplicate: The duplicate's setup is a good deal more complex. Most obviously, they're actually implementing a custom ErrorHandler and creating their own fault (which is where the issue was), which I'm not. Their answer doesn't apply to my situation.
Final solution: I ended up having to specify the Name/Namespace in both the FaultContract and when I was throwing the FaultException.
[ServiceContract(Namespace = "MyNamespace")]
public interface MyContract
{
[OperationContract]
[FaultContract(typeof(TDetail), Name = "TDetail"]
void ThrowException();
}
throw new FaultException<TDetail>(new TDetail("Test"),
"My test fault.",
new FaultCode("TDetail", "MyNamespace));
I'm not 100% yet on why it has to be that way, but at least it works!