【问题标题】:ContractFilter mismatch at the EndpointDispatcher (error handling)EndpointDispatcher 的 ContractFilter 不匹配(错误处理)
【发布时间】: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 才能工作。

提前致谢。

【问题讨论】:

    标签: c# .net wcf web-services


    【解决方案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>
              

              【讨论】:

              • 虽然您的回答可能会解决问题,但最好能说明问题所在以及您的回答如何解决问题。这是进一步改进这个和未来答案的建议。
              • 会牢记在心...!!感谢您的建议
              猜你喜欢
              • 2019-07-20
              • 2013-02-21
              • 1970-01-01
              • 2013-03-09
              • 2014-04-16
              • 1970-01-01
              • 2011-07-26
              • 1970-01-01
              • 2018-07-05
              相关资源
              最近更新 更多