2017-05-03 135 views
0

我試圖使用IErrorHandler interfcae實現WCF中的全局錯誤處理,但我想返回(在未處理的異常的情況下)一個簡單的字符串 (這是我的服務的返回類型)我怎麼能這是什麼? IErrorHandler中的ProvideFault方法將Message參數的'fault'參數設置爲消息類型,並且消息類型ToString()生成類似響應的XML,所以這對我不起作用 (因爲我的客戶端想要以特定格式獲取簡單的字符串)。WCF全局錯誤處理

感謝

+0

如果我理解正確 - 您的服務方法已經返回一個字符串。如果發生異常,您希望從服務中返回特定字符串? –

+0

@ScottHannen確實如此。我想從全局錯誤處理程序中執行此操作。 – eitanby

+0

我可以提供一種方法,它不是來自全局錯誤處理程序,但不需要您在每個服務方法中編寫相同的代碼。 –

回答

0

按照documentation

IErrorHandler使您能夠明確地控制SOAP錯誤產生

它不是爲改變服務的實際返回值。

如果我理解正確,你的服務已經返回一個字符串。如果發生錯誤,您希望服務返回特定的字符串。

最簡單的形式,這應該是這樣的:

public string YourServiceMethod(int someInput) 
{ 
    try 
    { 
     // Do whatever the method does 
    } 
    catch(Exception ex) 
    { 
     // Log the exception, probably? 
     return "This is the specific error message I want to return." 
    } 
} 

如果你想避免寫在每一個方法相同的代碼,來實現這一目標的方法之一是使用攔截器,如用Castle Windsor's dependency injection container

這意味着要修改整個WCF服務以使用Windsor(或一些類似的DI框架),但是由於很多其他原因,這是值得的。我爲我寫的每個WCF服務使用它。以下是關於如何在五分鐘內將Windsor添加到WCF服務的tutorial

然後你會寫一個叫做攔截器的類。它可能是這個樣子:

public class ErrorMessageInterceptor : IInterceptor 
{ 
    public void Intercept(IInvocation invocation) 
    { 
     try 
     { 
      invocation.Proceed(); 
     } 
     catch (Exception ex) 
     { 
      // log your exception 
      invocation.ReturnValue = "Your specific error message."; 
     } 
    } 
} 

然後,當你與容器註冊您服務,您這樣做:

container.Register(
    Component.For<IInterceptor>().ImplementedBy<ServerLogInterceptor>() 
     .Named("ErrorMessageInterceptor")); 

container.Register(Component.For<IYourService,YourService>() 
    .Interceptors("ErrorMessageInterceptor")); 

其中IYourService是您的服務接口和YourService是實際的服務類。

這意味着每次激活YourService的實例時,都會創建ErrorMessageInterceptor的實例。攔截器的Intercept方法會攔截所有對服務方法的調用。它實質上是在方法調用周圍放置一個try/catch而不直接將其添加到原始方法中。

如果你需要你可以更具體。例如,您的攔截器可以檢查invocation.Method.ReturnType以查看該方法是否返回字符串,然後只添加您的錯誤消息。

你可以用攔截器做一些很棒的事情。這種情況下,你想嘗試一些小事是一個嘗試與他們合作的好機會。如果你在使用DI之前看起來很奇怪,但是同樣一旦你嘗試了它,你可能會發現它是一個非常有用的模式。

+0

嗨, 坦克這個想法我真的不想在這個方向,但它是有意義的 和我已經改變我的代碼使用城堡,所以它看起來像我的需求的好選擇。 – eitanby