2010-08-11 120 views
29

在更新我的WCF客戶端的服務引用(只需點擊更新服務引用在Visual Studio 2008中)不匹配,出現下列錯誤:ContractFilter在EndpointDispatcher(錯誤處理)

System.ServiceModel。 FaultException: 由於在EndpointDispatcher的 處出現ContractFilter不匹配,因此無法在接收方 處理帶有動作 'http://schemas.xmlsoap.org/ws/2004/09/transfer/Get' 的消息。由於合同不匹配 (發件人與 收件人之間的不匹配操作)或發件人與 收件人之間的綁定/安全 不匹配,可能是 。檢查發件人和 收件人是否具有相同的合同和 相同的綁定(包括安全 要求,例如消息,傳輸, 無)。在 System.ServiceModel.Dispatcher.ErrorBehavior.ThrowAndCatch(例外 E,消息消息)

背景:

我已經創建ErrorServiceBehaviour類。因爲這種行爲是爲錯誤處理而創建的,所以IErrorHandler必須應用於每個ChannelDispatcher

public class ErrorServiceBehaviour : Attribute, IServiceBehavior 
{ 
    ... 
    public Type FaultType 
    { 
     get { return _faultType; } 
     set { _faultType = value; } 
    } 

    public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase) 
    { 
     foreach (ChannelDispatcher dispatcher in serviceHostBase.ChannelDispatchers) 
     { 
      dispatcher.ErrorHandlers.Add(new ErrorHandler(_faultType)); 
     } 
    } 
} 

public class ErrorHandler : IErrorHandler 
{ 
    public ErrorHandler(Type faultType) 
    { 
     _faultType = faultType;   
    } 
    ... 
} 

後來,我通過應用ErrorServiceBehavior屬性爲我服務類使用的行爲:

[ErrorServiceBehavior(FaultType = typeof(MyServiceFault))] 
public class MyService : IMyService 
{ 
    ... 
} 

的事情是,當我註釋掉foreach循環內ApplyDispatchBehavior方法,我得到沒有錯誤,但這不是出路(因爲我想要處理我的錯誤)。

下面有我的服務配置:

<system.serviceModel> 
    <services> 
     <service behaviorConfiguration="DefaultBehavior" name="MyService"> 
      <endpoint address="" binding="wsHttpBinding" contract="IMyService" bindingConfiguration="NoSecurityBinding"/> 
      <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/> 
     </service> 
    </services> 
    <behaviors> 
     <serviceBehaviors> 
      <behavior name="DefaultBehavior"> 
       <serviceMetadata httpGetEnabled="true" /> 
       <serviceDebug includeExceptionDetailInFaults="true" /> 
      </behavior> 
     </serviceBehaviors> 
    </behaviors> 
    <bindings> 
     <wsHttpBinding> 
      <binding name="NoSecurityBinding" > 
       <security mode="None"> 
        <transport clientCredentialType="None"/> 
        <message establishSecurityContext="false"/> 
       </security> 
      </binding> 
      <binding name="DefaultBinding" /> 
     </wsHttpBinding> 
    </bindings> 
</system.serviceModel> 

有人能幫助我嗎?前面所示

UPDATE

代碼:

foreach (ChannelDispatcher dispatcher in serviceHostBase.ChannelDispatchers) 
{ 
    dispatcher.ErrorHandlers.Add(new ErrorHandler(_faultType)); 
} 

增加了自定義錯誤處理所有端點 - 包括元數據之一。但實際上,這是而不是問題的根源 - 即使我禁止爲元數據端點添加錯誤處理,問題仍然會發生。

的其他通知是,當我改變的第一個端點的bindingConfigurationDefaultBinding,我沒有錯誤可言:

<services> 
    <service behaviorConfiguration="DefaultBehavior" name="MyService"> 
     <endpoint address="" binding="wsHttpBinding" contract="IMyService" bindingConfiguration="DefaultBinding"/> 
     <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/> 
    </service> 
</services> 

這種在還沒有我想要的選項 - 我還需要問題NoSecurityBinding工作。

在此先感謝。

回答

1

查看IExtensibleDataObject,它用於處理仍然可以相互通信的Web服務的不同版本。這樣合同就不需要完全匹配。希望這可以幫助。

0

在你說的好像是你的新WCF服務確實需要安全性,並在您NoSecurityBinding將其關閉。檢查 一種方法是讓WSDL文件本地,如果它有一個見:http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsdhttp://schemas.xmlsoap.org/ws/2004/09/policy或類似的進口。我敢肯定,你的更新WCF服務啓用了安全性


更新1

爲了讓您的問題,您可以使用WCF跟蹤的美好憧憬。在這裏,您可以看到如何打開它以及如何讀取這些痕跡:"How to turn on WCF tracing"

0

我不認爲您將安全性完全關閉。試試這個:

<bindings> 
     <wsHttpBinding> 
      <binding name="NoSecurityBinding" > 
       <security mode="None"> 
        <transport clientCredentialType="None"/> 
        <message clientCredentialType="None"/> 
       </security> 
      </binding> 
      <binding name="DefaultBinding" /> 
     </wsHttpBinding> 
    </bindings> 
0

現有的web.config設置可能會像以前的版本一樣產生問題。 最好從WCF客戶端應用程序中刪除現有的引用並再次添加引用。

0
<services> 
    <service behaviorConfiguration="ServiceBehaviour" name="Service"> 
    <endpoint address="" behaviorConfiguration="web" binding="webHttpBinding" contract="IService"> 
     <identity> 
     <dns value="localhost" /> 
     </identity> 
    </endpoint> 
    <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" /> 
    </service> 
</services> 
+2

儘管您的答案可能會解決問題,但如果您可以提供關於問題是什麼以及答案如何解決問題的說明,那將會更好。這是一個進一步改善這個和未來答案的建議。 – 2014-11-12 12:17:43

+0

將保持在我的腦海裏!感謝您的建議 – 2014-12-23 06:56:02

1

首先,我注意到你嘗試將mexHttpBinding綁定到終點,雖然它從未被你的「綁定」標籤內定義。這應該引起一個例外,我希望這樣的例外看起來像是困擾着你的例外。

<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/> 

... 

<bindings> 
    <mexHttpBinding> 
     THIS TAG WAS MISSING (add security features as needed) 
    </mexHttpBinding> 

    <basicHttpBinding> 
     <binding name="NoSecurityBinding" > 
      <security mode="None" /> 
     </binding> 
     <binding name="DefaultBinding" /> 
    </basicHttpBinding> 
</bindings> 

此外,由於您顯然不需要任何安全功能,因此您可能需要支持basicHttpBinding。正如very thorough answer所述,wsHttpBinding確實在想要安全功能時非常有用。

你的配置最終會變得幾乎一樣,將「ws」改爲「basic」。

<system.serviceModel> 
<services> 
    <service behaviorConfiguration="DefaultBehavior" name="MyService"> 
     <endpoint address="" binding="basicHttpBinding" contract="IMyService" bindingConfiguration="NoSecurityBinding"/> 
     <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/> 
    </service> 
</services> 
<behaviors> 
    <serviceBehaviors> 
     <behavior name="DefaultBehavior"> 
      <serviceMetadata httpGetEnabled="true" /> 
      <serviceDebug includeExceptionDetailInFaults="true" /> 
     </behavior> 
    </serviceBehaviors> 
</behaviors> 
<bindings> 
    <basicHttpBinding> 
     <binding name="NoSecurityBinding" > 
      <security mode="None" /> 
     </binding> 
     <binding name="DefaultBinding" /> 
    </basicHttpBinding> 
</bindings> 

+0

嗨。感謝您的回答。雖然自5年前問起這個問題以來,我不會去驗證它。不過,我很欣賞它。 – jwaliszko 2015-02-27 17:57:36

+0

哇,它在「沒有回答」的問題中陷入困境,我沒有想到系統推動這樣的老話題。無論如何,歡呼聲。 – 2015-02-27 18:04:04

1

檢查App.Config並確認它指向您部署了Windows服務主機或將其設置爲指向localhost