IIS でホストされ、WS HTTP バインディング (外部サービス) を使用する WCF サービスがあります。このサービスは、Net TCP (内部サービス) を介して、Windows サービスでホストされている 2 番目の WCF サービスを呼び出すことになります。内部サービスが をスローするFaultException
と、クライアントにスローするのではなく、外部サービスがクラッシュします。クライアントが見るのは、接続が強制的に閉じられていることだけです。
内部サービスは、Enterprise Library Validation Application Block を使用して受信メッセージを検証します。検証エラーが発生すると、サービスはFaultException<ValidationFault>
.
内部サービスと外部サービスの両方が[FaultContract(typeof(ValidationFault)]
、サービス コントラクトに属性を持っています。外部サービスをすぐに new をスローするように変更するとFaultException<ValidaitonFault>
、これはクライアントに問題なく返されます。内部サービスからの例外を外部サービスでキャッチできますが、再スローしようとしたり、新しい例外でラップしてスローしたりすると、IIS のアプリケーション プール全体がクラッシュします。イベント ログに役立つ情報が何も表示されないため、何が問題なのか正確にはわかりません。
外部サービスが内部サービスとの通信に使用するクライアント オブジェクトは、確実に閉じられ、正しく破棄されています。内部サービスの障害をクライアントに伝播するにはどうすればよいですか?
更新しました:
以下は、外部サービス コードの簡略版です。内部サービス呼び出しから検証エラーをキャッチできます。新品を投げればFaultException<ValidationFault>
大丈夫です。キャッチされた例外を使用すると、外部クライアントへの接続が切断されます。私が見ることができる唯一の違いは、サービスをデバッグするときです-キャッチされた例外を使用しようとすると、メソッドを終了するときにメッセージボックスが表示されます。
タイプ 'System.ServiceModel.FaultException`1' の未処理の例外が mscorlib.dll で発生しました
まったく新しい例外をスローすると、これは表示されません。おそらく答えは、検証エラーの詳細を新しいオブジェクトに手動でコピーすることですが、これはおかしいようです。
public class ExternalService : IExternalService
{
public ExternalResponse DoSomething(ExternalRequest)
{
try
{
var response = new ExternalResponse();
using (var internalClient = new InternalClient())
{
response.Data = internalClient.DoSomething().Data;
}
return response;
}
catch (FaultException<ValidationFault> fEx)
{
// throw fEx; <- crashes
// throw new FaultException<ValidationFault>(
// fEx.Detail as ValidationFault); <- crashses
throw new FaultException<ValidationFault>(
new ValidationFault(new List<ValidationDetail> {
new ValidationDetail("message", "key", "tag") }),
"fault message", new FaultCode("faultCode"))); // works fine!
}
}
}