自定义异常作为故障异常中的细节

uri*_*rig 5 .net wcf exception-handling faultexception

我试图在我的WCF服务的FaultException中抛出自己的自定义异常,并在我的WCF客户端中捕获它.但是,在客户端,异常将作为非泛型FaultException捕获,并且我的自定义异常的详细信息将丢失.

我的自定义例外是:

[Serializable] public class MyCustomException : ApplicationException 
{ ... }
Run Code Online (Sandbox Code Playgroud)

这是我扔它的方式:

throw new FaultException<MyCustomException>(new MyCustomException("foo bar!"));
Run Code Online (Sandbox Code Playgroud)

(请注意,我在接口中的方法上放置了[FaultContract(typeof(MyCustomException))]

以下是我尝试在客户端捕获它的方法:

...
catch (FaultException<MyCustomException> mcex)
{
    Console.WriteLine(mcex); 
}
 catch (FaultException fex) 
{
    Console.WriteLine(fex); 
}
Run Code Online (Sandbox Code Playgroud)

我的目标是在上面的第一个catch子句中捕获异常,但最终会在第二个catch子句中捕获.

奇怪的是,如果我用ApplicationException替换MyCustomException,那么确实正确捕获了FaultException.

我猜测问题是MyCustomException序列化为Serializable(而不是通过DataContractSerializer),也许我错过了一些WCF的附加指令.ServiceKnownType属性中的某些内容?(虽然我尝试过,但无济于事).

mar*_*c_s 3

是的,除非您在服务契约中将该类型指定为错误契约,否则您将无法捕获通用的FaultException:

[ServiceContract]
interface IYourService
{
   [OperationContract]
   [FaultContract(typeof(MyCustomException))]
   SomeReturnValue YourMethodCall(SomeInputValue input);
}
Run Code Online (Sandbox Code Playgroud)

只有执行此操作后,才能在客户端代码中捕获并处理特定的、通用类型的FaultException。

请参阅此博客文章中的 MSDN 文档,FaultException<T>了解有关 WCF 错误处理的更多背景信息和有用信息。

另外,我个人总是使用 [DataContract] 属性来装饰我的故障契约类(以及我想要使用 [DataMember] 序列化的所有成员):

[Serializable] 
[DataContract]
public class MyCustomException : ApplicationException 
{ ... }
Run Code Online (Sandbox Code Playgroud)