WCF 将服务异常(Exception)转换成 SOAP faults,传递到客户端后再次转换成 Exception。只不过缺省情况下,我们很难从中获取有意义的信息。
public interface ICalculate
{
[OperationContract]
int Add(int a, int b);
}
public class CalculateService : ICalculate
{
public int Add(int a, int b)
{
throw new Exception("错误!");
}
}
客户端调用 Add 方法触发异常,信息如下:
Server stack trace:
在 System.ServiceModel.Channels.ServiceChannel.ThrowIfFaultUnderstood(Message reply, MessageFault fault, String action, MessageVersion version, FaultConverter faultConverter)
......
(我们可以使用 "(host as ServiceHost).Description.Behaviors.Find<ServiceDebugBehavior>().IncludeExceptionDetailInFaults = true;" 来启动调试行为,这样也能看到具体的出错信息! )
当然,WCF 会提供一个包装异常类 FaultException 来帮助我们处理这些问题。
public interface ICalculate
{
[OperationContract]
int Add(int a, int b);
}
public class CalculateService : ICalculate
{
public int Add(int a, int b)
{
throw new FaultException(new Exception("错误!").Message);
}
}
这次输出的信息要友好得多。
Server stack trace:
在 System.ServiceModel.Channels.ServiceChannel.HandleReply(ProxyOperationRuntime operation, ProxyRpc& rpc)
......
另外,我们还可以通过 FaultContractAttribute 传递更详细的异常信息给客户端。
public class FaultMessage
{
[DataMember] public string Message;
[DataMember] public int ErrorCode;
}
[ServiceContract]
public interface ICalculate
{
[OperationContract]
[FaultContract(typeof(FaultMessage))]
int Add(int a, int b);
}
public class CalculateService : ICalculate
{
public int Add(int a, int b)
{
FaultMessage fault = new FaultMessage();
fault.Message = "错误信息!";
fault.ErrorCode = 1234;
throw new FaultException<FaultMessage>(fault, fault.Message);
}
}
客户端代码
{
CalculateClient client = new ConsoleApplication1.localhost.CalculateClient();
client.Add(1, 2);
}
catch (FaultException<FaultMessage> e)
{
Console.WriteLine("{0}; {1}", e.Detail.Message, e.Detail.ErrorCode);
}
-- 更详细的信息,请参考《WCF - FaultException》--