4

我正在尝试使用 WCF 实现一个通过 HTTP 接受 SOAP 1.2 的 Web 服务。不幸的是,我必须使用不将action参数作为 HTTP 标头的一部分发送的旧客户端。这似乎导致 WCF 出现问题,它(至少在默认情况下)似乎无法将请求路由到没有action.

我创建了一个基于BasicHttpBindingMessageVersion设置为的绑定MessageVersion.Soap12,我认为这将删除使用 WS-Addressing 的要求。

然后,我重载ApplyDispatchBehaviourIContractBehavior设置为根据 SOAP 主体的内容选择正确操作DispatchRuntime.OperationSelector的自定义实现(基本上是此 MSDN 文章中使用的方法)IDispatchOperationSelector

默认情况下,这似乎不起作用,并且在SelectOperation发出请求时不会调用该函数。

但是,如果我在合同中添加一个带有空操作的虚拟操作,如下所示:

[OperationContract( Action = "" )]
void DoNothing();

然后突然SelectOperation开始被调用,我的代码按预期工作。似乎我在使 WCF 不再需要操作标头方面没有成功——我刚刚停止了用于直接映射到操作的操作标头。但是,由于合约是从 .wsdl 文件生成的,因此编辑它以使其正常工作似乎是一个非常大的黑客攻击。

所以我的问题是:如何使用 WCF 在没有操作标头的情况下接受 SOAP 1.2 请求?除非我弄错了 SOAP 1.2 规范不需要操作标头,所以肯定有某种方法可以使用 WCF 实现这一点,而无需求助于破解合同?

4

1 回答 1

2

我今天才设法弄清楚这个问题的答案。事实证明,EndpointDispatcher正在使用的有一个ActionMessageFilter原样ContractFilter,这是根据操作过滤掉消息。

在我将 更新ContractFilter为 aMatchAllMessageFilter之后,所有消息都被传递到我IDispatchOperationSelector可以根据 SOAP 正文的内容选择它们的位置。

我用来执行此操作的代码位于IContractBehavior.ApplyDispatchBehaviour

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

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

于 2012-05-28T17:03:07.470 回答