5

WCFサービスからFaultException内に独自のカスタム例外をスローし、WCFクライアントでキャッチしようとしています。ただし、クライアント側では、例外は非ジェネリックのFaultExceptionとしてキャッチされ、カスタム例外の詳細は失われます。

私のカスタム例外は次のとおりです。

[Serializable] public class MyCustomException : ApplicationException 
{ ... }

これが私がそれを投げる方法です:

throw new FaultException<MyCustomException>(new MyCustomException("foo bar!"));

([FaultContract(typeof(MyCustomException))]がインターフェイスのメソッドの上に配置されていることに注意してください)

そして、これが私のクライアントでそれをキャッチしようとする方法です:

...
catch (FaultException<MyCustomException> mcex)
{
    Console.WriteLine(mcex); 
}
 catch (FaultException fex) 
{
    Console.WriteLine(fex); 
}

私の目標は、例外が上記の最初のcatch句でキャッチされることですが、2番目のcatch句でキャッチされることになります。

不思議なことに、MyCustomExceptionをApplicationExceptionに置き換えると、実際にFaultExceptionが適切にキャッチされます。

問題は、MyCustomExceptionがSerializableで(DataContractSerializer経由ではなく)シリアル化されていることと、WCFへの追加のディレクティブが欠落していることだと思います。ServiceKnownType属性の行に何かありますか?(私はそれを試しましたが、無駄になりました)。

4

1 に答える 1

3

はい、サービス コントラクトでその型を障害コントラクトとして指定するまで、汎用の FaultException をキャッチすることはできません。

[ServiceContract]
interface IYourService
{
   [OperationContract]
   [FaultContract(typeof(MyCustomException))]
   SomeReturnValue YourMethodCall(SomeInputValue input);
}

これを行うだけで、クライアント側のコードで特定の一般的に型指定された FaultException をキャッチして処理できます

WCF のエラー処理に関するその他の背景情報と適切な情報については、このブログ投稿のMSDN ドキュメントをFaultException<T>参照してください。

また、個人的には、[DataContract] 属性 (および [DataMember] でシリアル化したいすべてのメンバー) で障害コントラクト クラスを常に装飾します。

[Serializable] 
[DataContract]
public class MyCustomException : ApplicationException 
{ ... }
于 2010-01-26T17:10:29.683 に答える