I have asimple WCF HTTP/SOAP web service, the service implementation looks something like this:
public CustomResponse DoSomething(CustomRequest request)
{
try
{
return InternalGubbins.WithErrorHandling.ProcessRequest(request);
}
catch
{
// Some sort of error occurred that is not gracefully
// handled elsewhere in the framework
throw new SoapException("Hmmm, it would seem that the cogs are meshed!", SoapException.ServerFaultCode);
}
}
Now, if that SoapException is thrown I would like the exception message (i.e. Hmmm, it would seem that the cogs are meshed!
) to be returned to the invoking client without any additional exception detail (i.e. stack traces).
If I set includeExceptionDetailInFaults
to true (web.config on the server) then the full exception, with stack traces etc, is return to the 开发者_如何学Cclient. However if I set it to false, I get a generic message:
The server was unable to process the request due to an internal error. For more information about the error, either turn on IncludeExceptionDetailInFaults (either from ServiceBehaviorAttribute or from the configuration behavior) on the server in order to send the exception information back to the client, or turn on tracing as per the Microsoft .NET Framework 3.0 SDK documentation and inspect the server trace logs.
So the question is, how can I get my SoapException message back to the invoking client? i.e:
<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:a="http://www.w3.org/2005/08/addressing">
<s:Header>
<a:Action s:mustUnderstand="1">http://schemas.microsoft.com/net/2005/12/windowscommunicationfoundation/dispatcher/fault</a:Action>
<a:RelatesTo>urn:uuid:185719f4-6113-4126-b956-7290be375342</a:RelatesTo>
</s:Header>
<s:Body>
<s:Fault>
<s:Code>
<s:Value>s:Receiver</s:Value>
<s:Subcode>
<s:Value xmlns:a="http://schemas.microsoft.com/net/2005/12/windowscommunicationfoundation/dispatcher">a:InternalServiceFault</s:Value>
</s:Subcode>
</s:Code>
<s:Reason>
<s:Text xml:lang="en-GB">Hmmm, it would seem that the cogs are meshed!</s:Text>
</s:Reason>
</s:Fault>
</s:Body>
</s:Envelope>
I think you need to declare a FaultContract on the operation and use FaultException (SoapException is pre WCF). I believe WCF does not send faults back to the client if they are not part of the service contract. I have never tried SoapException but certainly throwing a FaultException has always worked fine for me.
[ServiceContract()]
public interface ISomeService
{
[OperationContract]
[FaultContract(typeof(MyFault))]
CustomResponse DoSomething(CustomRequest request)
}
public class SomeService
{
public CustomResponse DoSomething(CustomRequest request)
{
...
throw new FaultException<MyFault>(new MyFault());
}
}
If you don't want to define a custom exception type then try this
try
{
return InternalGubbins.WithErrorHandling.ProcessRequest(request);
}
catch
{
throw new FaultException("Hmmm, it would seem that the cogs are meshed.");
}
Doing so would send the following response to the client
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Header />
<s:Body>
<s:Fault>
<faultcode>s:Client</faultcode>
<faultstring xml:lang="en-US">Hmmm, it would seem that the cogs are meshed.</faultstring>
</s:Fault>
</s:Body>
</s:Envelope>
精彩评论