2014-09-27 81 views
-1

我正在使用WCF Service 4.5 F/W開發REST Full API。請建議如何將異常或任何業務驗證消息發送給客戶端。我正在尋找非常通用的解決方案,請提供最佳方式。 我已經嘗試了一些方法下面,WCF REST Full Service中的異常處理

  1. 設置OutgoingWebResponseContext之前發送響應客戶。

  2. 定義只能正常工作的故障契約添加服務引用(代理類)在REST FULL環境中不工作。

  3. 在catch塊中添加WebFaultException類。

  4. WCF Rest Starter Kit - 我收到了一些關於此的文章和文章,但他們的codeplex官方坐在建議不再可用。 link。所以,我不想這樣做。

這些工作不正常.. 我的示例代碼段: 接口:

[OperationContract] 
    [FaultContract(typeof(MyExceptionContainer))] 
    [WebInvoke(Method = "GET", UriTemplate = "/Multiply/{num1}/{num2}", BodyStyle = WebMessageBodyStyle.Wrapped,RequestFormat = WebMessageFormat.Xml, ResponseFormat = WebMessageFormat.Xml)] 
    string Multiply(string num1, string num2); 

實現:

  public string Multiply(string num1, string num2) 
    { 
     if (num1 == "0" || num2 == "0") 
     { 
      try 
      { 
       MyExceptionContainer exceptionDetails = new MyExceptionContainer(); 
       exceptionDetails.Messsage = "Business Rule violatuion"; 
       exceptionDetails.Description = "The numbers should be non zero to perform this operation"; 
       //OutgoingWebResponseContext outgoingWebResponseContext = WebOperationContext.Current.OutgoingResponse; 
       //outgoingWebResponseContext.StatusCode = System.Net.HttpStatusCode.ExpectationFailed; 
       //outgoingWebResponseContext.StatusDescription = exceptionDetails.Description.ToString(); 
       // throw new WebFaultException<MyExceptionContainer>(exceptionDetails,System.Net.HttpStatusCode.Gone); 
       throw new FaultException<MyExceptionContainer>(exceptionDetails,new FaultReason("FaultReason is " + exceptionDetails.Messsage + " - " + exceptionDetails.Description)); 
      } 
      catch (Exception ex) 
      { 
       throw new FaultException(ex.Message); 
      } 
     } 

     return Convert.ToString(Int32.Parse(num1) * Int32.Parse(num2)); 
    } 

的Web.Config:

<system.serviceModel> 
<services> 
    <service name="TestService.TestServiceImplementation" behaviorConfiguration="ServiceBehaviour"> 
    <endpoint binding="webHttpBinding" contract="TestService.ITestService" behaviorConfiguration="webHttp" > 
    </endpoint> 
    </service> 
</services> 
<behaviors> 
    <serviceBehaviors> 
    <behavior name="ServiceBehaviour"> 
     <!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment --> 
     <serviceMetadata httpGetEnabled="true"/> 
     <!-- To receive exception details in faults for debugging purposes, set the value below to true. Set to false before deployment to avoid disclosing exception information --> 
     <serviceDebug includeExceptionDetailInFaults="true"/> 
    </behavior> 
    </serviceBehaviors> 
    <endpointBehaviors> 
    <behavior name="webHttp" > 
     <webHttp helpEnabled="true" faultExceptionEnabled="true"/> 
    </behavior> 
    </endpointBehaviors> 
</behaviors> 
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" /> 

客戶:

try 
     { 
      string serviceUrl = "http://localhost:51775/TestService.cs.svc/Multiply/0/0"; 
      //Web Client 
      //WebClient webClient = new WebClient(); 
      //string responseString = webClient.DownloadString(serviceUrl); 
      WebRequest req = WebRequest.Create(serviceUrl); 
      req.Method = "GET"; 
      req.ContentType = @"application/xml; charset=utf-8"; 
      HttpWebResponse resp = req.GetResponse() as HttpWebResponse; 
      if (resp.StatusCode == HttpStatusCode.OK) 
      { 
       XmlDocument myXMLDocument = new XmlDocument(); 
       XmlReader myXMLReader = new XmlTextReader(resp.GetResponseStream()); 
       myXMLDocument.Load(myXMLReader); 
       Console.WriteLine(myXMLDocument.InnerText); 
      } 
      Console.ReadKey(); 
     } 
     catch (Exception ex) 
     { 
     Console.WriteLine(ex.Message); 
     } 

這是我的第一個問題,感謝所有熱情的開發者..!

回答

3

相反的FaultException,使用以下命令:

服務器:

catch (Exception ex) 
      { 
       throw new System.ServiceModel.Web.WebFaultException<string>(ex.ToString(), System.Net.HttpStatusCode.BadRequest); 
      } 

客戶:

catch (Exception ex) 
      { 
       var protocolException = ex as ProtocolException; 
       var webException = protocolException.InnerException as WebException; 
       if (protocolException != null && webException != null) 
       { 
        var responseStream = webException.Response.GetResponseStream(); 
        var error = new StreamReader(webException.Response.GetResponseStream()).ReadToEnd(); 
        throw new Exception(error); 
       } 
       else 
        throw new Exception("There is an unexpected error with reading the stream.", ex); 

      } 
+0

感謝您的回覆。我嘗試過使用WebFaultException,但沒有運氣仍然無法獲得客戶端的實際異常 – 2014-09-29 04:30:16

+0

@SJAlex請參閱我的更新,瞭解如何獲取catch和處理異常。還有其他方法可以通過投射例外,但我這樣做。 – 2014-09-29 15:20:25

0

在WCF創建真正的休息幾乎是不可能的,但借力httpprotocol的部分當然是可能的。

要控制你的服務的錯誤信息,你必須提供一個錯誤處理程序(一個我ErrorHandler實現),它掛接到WCF的堆棧和覆蓋任何錯誤處理在這裏被定義。

該接口包含兩種方法。一個告訴wcf它是否可以處理某個異常(bool HandleError),如果HandleError返回true,則調用另一個異常。第二種方法ProvideFault允許您定義在出現異常情況時如何響應客戶端。

您可以鏈處理程序來獲得更多的粒度。而且因爲你在做其他你應該使用httpstatus代碼告知錯誤條件適用。

http://blogs.msdn.com/b/carlosfigueira/archive/2011/06/07/wcf-extensibility-ierrorhandler.aspx

http://www.remondo.net/wcf-global-exception-handling-attribute-and-ierrorhandler/