2010-08-03 71 views
0

我有一個託管在IIS中的WCF服務,並使用WS HTTP綁定(外部服務)。此服務最終通過Net TCP(內部服務)調用託管在Windows服務中的第二個WCF服務。當內部服務拋出FaultException時,外部服務崩潰而不是拋到客戶端。所有客戶看到的是連接被強制關閉。WCF FaultException - 當從內部WCF調用中「重新拋出」時崩潰應用程序池

內部服務使用企業庫驗證應用程序塊來驗證傳入消息。當發生驗證錯誤時,服務會拋出FaultException<ValidationFault>

服務合同中的內部和外部服務都有[FaultContract(typeof(ValidationFault)]屬性。如果我將外部服務更改爲立即拋出新的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! 
     } 
    } 
} 

回答

0

好,它的工作原理,如果我這樣做,但必須有一個更好的辦法...

這似乎只是FaultException<ValidationFault>的問題。我可以重新投擲FaultExceptionFaultException<SomethingElse>對象,沒有任何問題。

try 
{ 
    DoStuff(); 
} 
catch (FaultException<ValidationFault> fe) 
{ 
    throw this.HandleFault(fe); 
} 

... 

private FaultException<ValidationFault> HandleFault(
    FaultException<ValidationFault> fex) 
{ 
    var validationDetails = new List<ValidationDetail>(); 
    foreach (ValidationDetail detail in fex.Detail.Details) 
    { 
     validationDetails.Add(detail); 
    } 

    return new FaultException<ValidationFault>(
     new ValidationFault(validationDetails)); 
} 
0

我的設計和你幾乎完全一樣,碰到了類似的問題(不知道是否有碰撞,但!)。

如果我沒有記錯的話,即使ValidationFault是一個常見的類,當故障在線路上傳輸時,類型是特定於WCF接口的。我認爲這是因爲Web服務上的命名空間限定符(但是這是一段時間,所以我可能會錯誤)。

這不是非常優雅,但我所做的是手動重新拋出的異常:

try 
{ 
    DoStuff(); 
} 
catch (FaultException<ValidationFault> fe) 
{ 
    HandleFault(fe); 
    throw; 
} 

... 

private void HandleFault(FaultException<ValidationFault> fe) 
{ 
    throw new FaultException<ValidationFault>(fe.Detail as ValidationFault); 
} 
+0

感謝您的建議,但不幸的是,它沒有奏效。如果這有什麼用處,我已經爲這個問題添加了更多的細節。 – 2010-08-04 07:52:42