我正在尝试使用WCF实现一个通过HTTP接受SOAP 1.2的Web服务。不幸的是,我必须使用不发送action
参数作为HTTP标头一部分的旧客户端。这似乎导致WCF出现问题,(至少默认情况下)似乎无法将请求路由到没有action
的适当位置。
我已经基于BasicHttpBinding
创建了绑定,但MessageVersion
设置为MessageVersion.Soap12
,我认为这会删除使用WS-Addressing的要求。
然后我在ApplyDispatchBehaviour
中重载IContractBehavior
以将DispatchRuntime.OperationSelector
设置为IDispatchOperationSelector
的自定义实现,该实现根据SOAP正文的内容选择正确的操作(基本上是this MSDN article)中使用的方法
默认情况下,这似乎不起作用,并且在发出请求时不会调用SelectOperation
函数。
但是,如果我在合同中添加一个空操作的虚拟操作,就像这样:
[OperationContract( Action = "" )]
void DoNothing();
然后突然SelectOperation
开始被调用,我的代码按预期工作。看起来我没有成功使WCF不再需要动作头 - 我刚刚停止了用于直接映射到操作的动作头。但是,由于合同是从.wsdl文件生成的,所以编辑它似乎是一个非常大的黑客,以便让事情发挥作用。
所以我的问题是:如何在没有使用WCF的动作头的情况下接受SOAP 1.2请求?除非我弄错了SOAP 1.2规范不需要动作头,所以肯定有一些方法可以用WCF实现这个,而不需要破解合同吗?
答案 0 :(得分:1)
我今天刚刚设法解决了这个问题的答案。事实证明,正在使用的EndpointDispatcher
有一个ActionMessageFilter
,因为它是ContractFilter
,而这是根据操作筛选出的消息。
将ContractFilter
更新为MatchAllMessageFilter
后,所有邮件都会传递到我的IDispatchOperationSelector
,根据SOAP正文的内容可以选择它们。
我以前使用的代码是IContractBehavior.ApplyDispatchBehaviour
:
foreach(
var endpointDispatcher in
dispatchRuntime.ChannelDispatcher.Endpoints
)
{
endpointDispatcher.ContractFilter = new MatchAllMessageFilter();
}
我可能会在将来更新为使用比MatchAllMessageFilter
更合适的过滤器,但现在它正在完成这项工作。