使用WCF实现不需要操作头的SOAP服务器

时间:2012-05-23 12:32:52

标签: wcf web-services soap header wcf-binding

我正在尝试使用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实现这个,而不需要破解合同吗?

1 个答案:

答案 0 :(得分:1)

我今天刚刚设法解决了这个问题的答案。事实证明,正在使用的EndpointDispatcher有一个ActionMessageFilter,因为它是ContractFilter,而这是根据操作筛选出的消息。

ContractFilter更新为MatchAllMessageFilter后,所有邮件都会传递到我的IDispatchOperationSelector,根据SOAP正文的内容可以选择它们。

我以前使用的代码是IContractBehavior.ApplyDispatchBehaviour

foreach(
    var endpointDispatcher in
    dispatchRuntime.ChannelDispatcher.Endpoints
    )
{
    endpointDispatcher.ContractFilter = new MatchAllMessageFilter();
}

我可能会在将来更新为使用比MatchAllMessageFilter更合适的过滤器,但现在它正在完成这项工作。