2011-01-11 37 views
3

我剛剛注意到一些特殊情況。我有一個通過basicHttpBinding發佈的內部庫存服務,以及啓用了元數據的customBinding(http +二進制)。我還爲http提供了一個mex端點。我們使用Visual Studio 2008 & VB.NET使用包含System.Exception的自定義FaultContract對象會導致「添加服務引用」失敗

就在最近我們注意到,我們無法在其他項目中成功添加對此服務的服務引用。它所產生的只是我們通過FaultContract包含的第一個自定義異常(實際上只有一種類型)。如果我添加一個簡單的Web引用,它也會正常工作。另外,WcfClient.exe在加載服務時也沒有問題。只是VS.NET添加服務引用不起作用。

在該服務中,此異常從Exception繼承並標記爲可序列化。這就是你應該做的,不是嗎?

無論如何,這讓我感到莫名其妙。如果我刪除此自定義異常的FaultContract一切正常。我可以添加一個服務引用,沒問題。但是有沒有一種方法可以讓我自定義異常?這是一個已知的問題嗎?

+0

您當然認識到,對於.NET以外的任何平臺,Exception都沒有意義? – 2011-02-08 02:26:52

+0

不,但我對它的印象是,WCF框架需要從Exception中引入Inclusion。這也是我認爲是正確的,因爲它始終能夠爲從Exception繼承的自定義異常創建正確的代理類。 – SpoBo 2011-02-15 10:51:20

回答

8

今天我碰到了這個。解決方案是使用FaultContract中不從Exception繼承的對象。如果您查看FaultExceptionFaultContract的MSDN文檔,您將看到官方示例使用普通類(具有DataContact屬性),而不是爲FaultException.Detail擴展Exception的類。我不確定爲什麼Exception導致添加服務引用失敗,但我懷疑它與序列化或檢索自定義異常的類型信息有關。我已經在示例實現之前和之後包括了工作方法。對於使用他的代碼Max Strini和尋找解決方案幫助:

之前(沒有工作):

[ServiceContract] 
public interface IMyService 
{ 
    [OperationContract] 
    [FaultContract(typeof(MyException))] 
    MyResults MyServiceOperation(string myParameter); 
} 

[Serializable] 
public class MyException : Exception 
{ 
    public string CustomData { get; set; } 
} 

[ErrorHandlerBehavior(typeof(MyErrorHandler))] 
public class MyService : IMyService 
{ 
    public MyResults MyServiceOperation(string myParameter) 
    { 
     ... 
     throw new MyModelException { CustomData = "42" }; 
     ... 
    } 
} 

public class MyErrorHandler : IErrorHandler 
{ 
    public bool HandleError(Exception error) { return false; } 

    public void ProvideFault(Exception error, MessageVersion version, ref Message fault) 
    { 
     try { throw error; } 
     catch (MyModelException ex) 
     { 
      var faultEx = new FaultException<MyException>(new MyException { CustomData = ex.CustomData }); 
      fault = Message.CreateMessage(version, faultEx.CreateMessageFault(), faultEx.Action); 
     } 
     catch { /* Supress all others */ } 
    } 
} 

後(工作):

[ServiceContract] 
public interface IMyService 
{ 
    [OperationContract] 
    [FaultContract(typeof(MyFault))] 
    MyResults MyServiceOperation(string myParameter); 
} 

[DataContract] 
public class MyFault 
{ 
    [DataMember] 
    public string CustomData { get; set; } 
} 

[ErrorHandlerBehavior(typeof(MyErrorHandler))] 
public class MyService : IMyService 
{ 
    public MyResults MyServiceOperation(string myParameter) 
    { 
     ... 
     throw new MyModelException { CustomData = "42" }; 
     ... 
    } 
} 

public class MyErrorHandler : IErrorHandler 
{ 
    public bool HandleError(Exception error) { return false; } 

    public void ProvideFault(Exception error, MessageVersion version, ref Message fault) 
    { 
     try { throw error; } 
     catch (MyModelException ex) 
     { 
      var faultEx = new FaultException<MyFault>(new MyFault { CustomData = ex.CustomData }); 
      fault = Message.CreateMessage(version, faultEx.CreateMessageFault(), faultEx.Action); 
     } 
     catch { /* Supress all others */ } 
    } 
} 

來源這個問題。

+0

thx :)我總是假設WCF需要一個對象,它包含或者是從異常繼承的東西,以創建一個合適的FaultException。 – SpoBo 2011-02-15 10:50:10

+0

這很好。我必須使用svcutil從WSDL生成服務,但我無法弄清楚如何處理異常。這個答案解決了我的問題,謝謝! – Zoidberg 2012-05-22 15:15:17

0

我也遇到了這個問題。我結束了使用svcutil.exe生成代理似乎沒有遭受同樣的問題。

+0

唯一真正的解決方法是不使用Exception類派生模型(或可能是任何.NET Core類模型)作爲DataMember。只要將自己限制在POCO的範圍內,您的WCF合同就會正確,清晰並且與其他技術更加兼容。 (Java,PHP等) – SpoBo 2011-09-12 09:53:28

0

我有同樣的問題,並通過使用SVCUTIL.exe生成代理來解決它。我按照MSDN建議的方式完成了自定義錯誤設置,但「添加服務引用」不包括代理中的錯誤合同。然後我用的SvcUtil工具,它像變魔術一樣:)

相關問題