2014-04-15 82 views
0

我試圖在IE中使用IErrorHandler接口實現WCF中的自定義錯誤處理。我想將未處理的異常翻譯成自定義錯誤,這是我在XSD中獲得的結構。WCF - 使用自定義錯誤消息替換故障SOAP消息的故障節點

我的代碼如下所示:

public void ProvideFault(Exception error, MessageVersion version, ref Message fault) 
{ 
    if (!(error is FaultException)) 
    { 
     var customFault = new MyCustomFault 
     { 
      FaultString = "Something gone wrong", 
      Detail = new DetailType 
      { 
       GeneralFault = new GeneralFaultType 
       { 
        Errors = new[] 
        { 
         new ErrorType 
         { 
           Code = "333" 
         } 
        } 
       } 
      } 
     }; 

     var faultException = new FaultException<MyCustomFault>(customFault); 
     var msgFault = faultException.CreateMessageFault(); 
     fault = Message.CreateMessage(version, msgFault, faultException.Action); 
    } 
} 

但這個代碼將產生輸出SOAP消息

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"> 
    <s:Body> 
     <s:Fault> 
     <faultcode>s:Client</faultcode> 
     <faultstring xml:lang="cs-CZ">The creator of this fault did not specify a Reason.</faultstring> 
     <detail> 
... MyCustomFault goes here... 
     </detail> 
     </s:Fault> 
    </s:Body> 
</s:Envelope> 

我能夠影響故障的唯一細節元素。我想實現,而不是來自namespece「http://schemas.xmlsoap.org/soap/envelope/」的故障元素將成爲我的自定義故障對象。這甚至可能嗎?我正在使用XmlSerializer。

謝謝 米哈爾

回答

1

不,不幸的是,這是不可能的。 WCF服務通過soap錯誤消息通知客戶端錯誤的唯一方法。因此WCF服務必須遵循soap規範。

以下規格說明所有故障消息必須具有相同的結構。請參閱規範:SOAP 1.2,查找第5.4.6節「SOAP錯誤代碼」。您可以在其中找到並示例(與您提供的幾乎相同)以及所有節點的描述。

在SOAP 1.2中引入了詳細節點(請參考規範:第5.4.5節SOAP細節元素)。

提供您的錯誤契約,您可以在此處(在Detail元素中)以xml形式注入您的自定義錯誤。但其他XML結構是不可更改的。

0

如果您需要遵循供應商的規範,您可以選擇定義xml序列化,然後生成xmlReader,然後將該讀取器傳遞給消息。我做了類似的,所以我可以單元測試行爲/ messageInspector是固定的故障在未來的東西。

var xtr = new XmlTextReader("CustomSoapFault.xml"); 

// I'm only allocating 1MB, you could allocate more if needed 
var message = Message.CreateMessage(xtr, 1024 * 1024, MessageVersion.Soap11); 

CustomSoapFault.xml內容是

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"> 
    <s:Body> 
     <s:Fault> 
      ... CustomFault goes here... 
     </s:Fault> 
    </s:Body> 
</s:Envelope> 

當.NET生成與此消息時,Message.IsFault財產將返回true。

此外,請確保更新soap的名稱空間和MessageVersion,以便它們匹配。