EndpointDispatcher 的 ContractFilter 不匹配(错误处理)

Posted

技术标签:

【中文标题】EndpointDispatcher 的 ContractFilter 不匹配(错误处理)【英文标题】:ContractFilter mismatch at the EndpointDispatcher (error handling) 【发布时间】:2011-03-28 09:36:11 【问题描述】:

更新我的 WCF 客户端的服务引用时(只需在 Visual Studio 2008 中单击 更新服务引用),出现以下错误:

System.ServiceModel.FaultException: 带有动作的消息 'http://schemas.xmlsoap.org/ws/2004/09/transfer/Get' 无法在接收方处理, 由于 ContractFilter 不匹配 端点调度程序。这可能是 因为合同不匹配 (发送方和发送方之间的操作不匹配 接收者)或绑定/安全 发件人和收件人不匹配 接收者。检查发件人和 接收方具有相同的合同和 相同的绑定(包括安全 要求,例如消息,传输, 没有)。在 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

   ...

问题是,当我在 ApplyDispatchBehavior 方法中注释掉 foreach 循环时,我得到 no 错误,但这不是出路(因为我希望我的错误处理)。

下面是我的服务配置:

<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>

有人可以帮我吗?

更新

前面显示的代码:

foreach (ChannelDispatcher dispatcher in serviceHostBase.ChannelDispatchers)

    dispatcher.ErrorHandlers.Add(new ErrorHandler(_faultType));

为所有端点添加自定义错误处理 - 包括元数据之一。但实际上这不是问题的根源 - 即使我禁用为元数据端点添加错误处理,问题仍然存在。

另一个通知是,当我将第一个端点的bindingConfiguration 更改为DefaultBinding 时,我根本没有 no 错误:

<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 服务。这样合同就不需要完全匹配。希望这会有所帮助。

【讨论】:

【参考方案2】:

首先,我注意到您尝试将 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>

【讨论】:

嗨。感谢您的回答。我不打算验证它,因为这个问题是在大约 5 年前被问到的。不过我很感激。 哇,突然出现在“未回答”的问题中,没想到系统会推送这么老的话题。无论如何,干杯。【参考方案3】:

检查App.Config 并验证它是否指向您部署的Windows 服务主机或将其设置为指向localhost

【讨论】:

【参考方案4】:

根据您的说法,您的新 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"

【讨论】:

【参考方案5】:

我认为您并没有完全关闭安全性。试试这个:

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

【讨论】:

【参考方案6】:

现有的 web.config 设置可能会像以前的版本一样产生问题。 最好从 WCF 客户端应用程序中删除现有引用并再次添加引用。

【讨论】:

【参考方案7】:
<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>

【讨论】:

虽然您的回答可能会解决问题,但最好能说明问题所在以及您的回答如何解决问题。这是进一步改进这个和未来答案的建议。 会牢记在心...!!感谢您的建议

以上是关于EndpointDispatcher 的 ContractFilter 不匹配(错误处理)的主要内容,如果未能解决你的问题,请参考以下文章

由于 EndpointDispatcher 的 ContractFilter 不匹配,接收方无法处理带有 Action '' 的消息。

EndpointDispatcher 的 ContractFilter 不匹配?

EndpointDispatcher 处的 AddressFilter 不匹配 - 带有 To 的 msg

EndpointDispatcher 的 ContractFilter 不匹配(错误处理)

EndpointDispatcher 错误处的 WCF ContractFilter 不匹配

红移中的 PERCENTILE_CONT()