2010-09-13 35 views
2

希望有一些WCF嚮導可以在這裏發現我的錯誤。WCF IErrorHandler擴展沒有返回指定的錯誤

我正在嘗試通過基於IErrorHandler的RESTful JSON WCF服務上的behaviorExtension設置全局錯誤處理程序。該方法被裝飾成這樣:

[OperationContract] 
[WebGet(UriTemplate = "screens/info", ResponseFormat = WebMessageFormat.Json)] 

的IErrorHandler實現如下:

public class ErrorHandler : IErrorHandler 
{ 
    public void ProvideFault(Exception error, 
          MessageVersion version, 
          ref Message fault) 
    { 
     var error = new JsonError 
         { 
          Message = error.Message, 
          FaultCode = -1, 
          StackTrace = error.StackTrace 
         }; 

     fault = Message.CreateMessage(version, 
        "", 
        ideaScreeningError, 
        new DataContractJsonSerializer(
         ideaScreeningError.GetType())); 

     // tell WCF to use JSON encoding rather than default XML 
     var wbf = new WebBodyFormatMessageProperty(WebContentFormat.Json); 
     fault.Properties.Add(WebBodyFormatMessageProperty.Name, wbf); 

     //Modify response 
     var rmp = new HttpResponseMessageProperty 
         { 
          StatusCode = HttpStatusCode.BadRequest, 
          StatusDescription = "Bad Request" 
         }; 

     fault.Properties.Add(HttpResponseMessageProperty.Name, rmp); 
    } 

    public bool HandleError(Exception error) 
    { 
     return true; 
    } 
} 

我可以驗證(通過斷點),所述延伸部被調用並且被適當地執行。當我在瀏覽器中查看AJAX調用的結果時,我可以看到WCF仍然返回500內部服務器錯誤,而不是我在錯誤處理程序中指定的錯誤詳細信息。

如果我更改WCF方法中引發的異常類型,這些反映在瀏覽器中的結果中,所以我可以推測WCF正在做一些事情來處理異常並在內部返回一些內容。

我該如何讓它停止!?

編輯

我加入了自定義行爲元素:

public class ErrorBehaviorElement : BehaviorExtensionElement 
{ 
    protected override object CreateBehavior() 
    { 
     return new ErrorBehavior(); 
    } 

    public override Type BehaviorType 
    { 
     get { return typeof(ErrorBehavior); } 
    } 
} 

與行爲:

internal class ErrorBehavior : WebHttpBehavior 
{ 
    protected override void AddServerErrorHandlers(ServiceEndpoint endpoint, 
     EndpointDispatcher endpointDispatcher) 
    { 
     // clear default error handlers. 
     endpointDispatcher.ChannelDispatcher.ErrorHandlers.Clear(); 

     // add the Json error handler. 
     endpointDispatcher.ChannelDispatcher.ErrorHandlers.Add(
      new ErrorHandler()); 
    } 
} 
+0

如何將新的錯誤處理程序添加到服務中? – 2010-09-13 19:13:02

+0

@Ladislav - 通過web.config自定義BehaviorExtensionElement – 2010-09-13 19:22:16

+0

是的,我明白,但我對你的自定義行爲感興趣。 – 2010-09-13 19:37:28

回答

5

這裏的問題在於WCF Rest Starter Kit(我沒有意識到它在使用,因爲我沒有啓動這個項目),更具體地說WebServiceHost2。我在反射器打開ServiceHost的,發現OnOpening()這個可愛的一小段代碼:

if (endpoint.Behaviors.Find<WebHttpBehavior>() != null) 
{ 
    endpoint.Behaviors.Remove<WebHttpBehavior>(); 
    WebHttpBehavior2 item = new WebHttpBehavior2(); 
    // other code omitted 
    endpoint.Behaviors.Add(item); 
} 

正如你所看到的,不管你想要添加到終點什麼樣的行爲,只要它從WebHttpBehavior的休息開始繼承工具包組件會劫持你的處理程序,刪除它,並用它自己的替換它。

請記住,WebHttpBehavior2也從WebHttBehavior繼承,所以從我的擴展中的WebHttpBehavior2繼承沒有任何幫助的事情。

的第一步是創建一個從WebServiceHost2派生的新WebSeriveHost和壓倒OnOpening()並重新劫持什麼休息入門工具包偷走了我:

if(endpoint.Behaviors.Find<WebHttpBehavior>() != null) 
{ 
    endpoint.Behaviors.Remove<WebHttpBehavior>(); 
    var item = ErrorBehavior(); 
    // other code 
    endpoint.Behaviors.Add(item); 
} 

,然後創建一個返回我的自定義一個新的WebServiceHostFactory WebServiceHost類型。

+0

不錯,我討厭這樣的功能,只是改變了邏輯,甚至沒有告訴你,感謝上帝,我們有反射器。 – 2010-09-14 21:16:29

0

不要忘記設置響應的ContentType以及:

rmp.Headers[HttpResponseHeader.ContentType] = "application/json"; 
0

基於評論,我會嘗試刪除常見的webHttpBehavior。你已經定義了你自己的行爲來源於webHttp。沒有理由在您的服務配置中有兩個webHttp行爲。此外,webHttp行爲會添加自己的錯誤處理程序,其行爲與您描述的完全相同。也許它不會幫助,但你可以試試看。

+0

奇怪的是,當我刪除webHttpBehavior時,我的擴展不再被調用來處理異常 – 2010-09-14 12:46:21

+0

我發現問題是什麼(最後),這是完全出乎意料的,我爲你發佈瞭解決方案 – 2010-09-14 21:08:50

相關問題