使用 WCF 服务时,您必须使用 FaulException,因为它是处理错误的本机 Soap 方法(异常也是不可序列化的)。
在典型场景中,您将首先在每个操作合同上添加类型化的 FaultContract。
// NOTE: This is the std wcf template
[ServiceContract]
public interface IService1
{
[FaultContract(typeof(int))]
[FaultContract(typeof(string))]
[FaultContract(typeof(DateTime))]
[OperationContract]
string GetData(int value);
}
您的服务将为您决定客户端需要故障信息的所有故障情况发送键入的故障异常。
您的客户端可以捕获表示操作合同中指定的自定义 SOAP 错误的 FaultException 类型。
ServiceReference1.Service1Client proxy = new ServiceReference1.Service1Client();
try
{
Console.WriteLine("Returned: {0}", proxy.GetData(-5));
}
catch (FaultException<int> faultOfInt)
{
//TODO
proxy.Abort();
}
catch (FaultException<string> faultOfString)
{
//TODO
proxy.Abort();
}
catch (FaultException<DateTime> faultOfDateTime)
{
//TODO
proxy.Abort();
}
catch (FaultException faultEx)
{
Console.WriteLine("An unknown exception was received. "
+ faultEx.Message
+ faultEx.StackTrace
);
proxy.Abort();
}
catch (Exception e)
{
//generic method
Type exceptionType = e.GetType();
if (exceptionType.IsGenericType && exceptionType.GetGenericTypeDefinition() == typeof(FaultException<>))
{
PropertyInfo prop = exceptionType.GetProperty("Detail");
object propValue = prop.GetValue(e, null);
Console.WriteLine("Detail: {0}", propValue);
}
else
{
Console.WriteLine("{0}: {1}", exceptionType, e.Message);
}
}
最后,由于 FaultException 继承了 Exception,您仍然可以使用反射来获取内部故障类型和详细信息,如下所示。
另请注意,来自 WCF 客户端上的通信方法的常见预期异常包括 TimeoutException、CommunicationException 和 CommunicationException 的任何派生类(如 FaultException)。这些表示通信过程中出现问题,可以通过中止 WCF 客户端并报告通信故障来安全地处理该问题。