4

单层应用程序可以通过以下方式区分异常:

Exception ex;

if (ex is System.DirectoryServices.AccountManagement.PasswordException)
    ...

其中 ex 只是一个通用的例外。

当您迁移到 WCF 进行多层时,您将失去所有这些,您需要使用 FaultException 机制。

问题是我找不到任何方法来执行上述操作。

在我的客户端中,我想捕获 FaultException 类型,然后区分它们,例如:

catch (FaultException ex)
{
    if FaultException is (PasswordExceptionFault)
      ...
    etc
}

有没有办法做到这一点?

否则我必须有许多 catch 构造——每种类型的 FaultException 一个。

4

2 回答 2

8

使用 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 客户端并报告通信故障来安全地处理该问题。

于 2013-04-16T20:21:59.180 回答
-2

只需使用类似的东西:

if (error is FaultException<ServerTooBusyException>) 
{
    // Do something
}
于 2015-03-10T00:23:27.293 回答