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.xsd 或 http://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 不匹配(错误处理)