2010-08-11 117 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