在更新我的WCF客户端的服务引用时(只需在Visual Studio 2008中单击更新服务引用),发生以下错误:
System.ServiceModel.FaultException: 带有Action的消息 'http://schemas.xmlsoap.org/ws/2004/09/transfer/Get' 不能在接收器处理, 由于ContractFilter不匹配 EndpointDispatcher。这可能是 因为合同不匹配 (发件人和发件人之间不匹配的行为) 接收者)或绑定/安全 发件人和发件人之间不匹配 接收器。检查发件人和 接收者有相同的合同和 相同的绑定(包括安全性 要求,例如消息,运输, 没有)。在 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>
有人可以帮助我吗?
更新
前面显示的代码:
foreach (ChannelDispatcher dispatcher in serviceHostBase.ChannelDispatchers)
{
dispatcher.ErrorHandlers.Add(new ErrorHandler(_faultType));
}
为所有端点添加自定义错误处理 - 包括元数据。但实际上这是不问题的根源 - 即使我禁用为元数据端点添加错误处理,问题仍然存在。
另一个通知是,当我将第一个端点的bindingConfiguration
更改为DefaultBinding
时,我发现没有错误:
<services>
<service behaviorConfiguration="DefaultBehavior" name="MyService">
<endpoint address="" binding="wsHttpBinding" contract="IMyService" bindingConfiguration="DefaultBinding"/>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
</service>
</services>
这样的选择也不是我想要的 - 我仍然需要有问题的NoSecurityBinding
才能工作。
提前致谢。
答案 0 :(得分:1)
查看IExtensibleDataObject,它用于处理仍然能够相互通信的Web服务的不同版本。这样合同就不需要完全匹配。希望这会有所帮助。
答案 1 :(得分:1)
首先,我注意到您尝试将 mexHttpBinding 绑定到端点,尽管它从未在您的&#34; Bindings&#34;中定义。标签。这应该是一个例外,我希望这样的例外看起来像是困扰你的那个。
<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非常有用。
您的配置最终会变得几乎相同,更改&#34; ws&#34;为&#34;基本&#34;。
<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>
答案 2 :(得分:1)
检查App.Config
并验证它是否指向已部署的Windows服务主机,或将其设置为指向localhost
。
答案 3 :(得分:0)
根据您的说法,您的新 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"
答案 4 :(得分:0)
我不认为你完全取消了安检。试试这个:
<bindings>
<wsHttpBinding>
<binding name="NoSecurityBinding" >
<security mode="None">
<transport clientCredentialType="None"/>
<message clientCredentialType="None"/>
</security>
</binding>
<binding name="DefaultBinding" />
</wsHttpBinding>
</bindings>
答案 5 :(得分:0)
现有的web.config设置可能会产生问题,因为它们适用于以前的版本。 最好从WCF客户端应用程序中删除现有引用并再次添加引用。
答案 6 :(得分: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>