挂钩到第 3 方 Web 服务 (WCF) 调用
Posted
技术标签:
【中文标题】挂钩到第 3 方 Web 服务 (WCF) 调用【英文标题】:Hooking into 3rd Party Web Service (WCF) calls 【发布时间】:2013-03-03 02:35:13 【问题描述】:在我的工作场所,我们正在升级我们的考勤设置。目前,我们有员工用来办理入住和退房的实体终端。这些终端通过 Web 服务调用与第 3 方 T&A 系统进行通信。
关于 T&A 网络服务:
托管在 IIS 6 上 通过 HTTP 使用 WCF 进行通信 我们只对其中一种公开的方法感兴趣(我们称之为 Beep())我需要做什么:
保留原来的 T&A 系统,原封不动 编写一个自定义服务,也响应对 Beep() 的调用因此,基本上,我需要搭载对 Beep() 的所有调用,但我不确定最好的方法是什么。
已经考虑过的:
-
编写一个自定义 Web 服务,该服务实现与 T&A 服务完全相同的合同,并将所有终端定向到该自定义服务。我的想法是我可以从我的自定义服务中调用原始 T&A 服务,以及应用所需的任何其他逻辑。
这对我来说似乎太过分了,而且似乎有不必要的风险。我们希望尽可能不修改原始系统。
编写自定义 HTTP 处理程序来拦截对原始 T&A 服务的调用。
我们实际上已经在内部做过类似的事情,但我们的实现采用原始 HttpRequest,提取内容,调用自定义服务,最后基于原始请求创建一个 new HttpRequest以便进行对 Beep() 的原始 Web 服务调用。
我不喜欢这种方法的地方是原始的 HttpRequest 丢失了。是的,创建了第二个据称相同的请求,但我对 HttpRequests 的了解还不够,无法保证这是安全的。
我更喜欢选项 2,但它仍然不完美。理想情况下,我们不需要销毁原始的 HttpRequest。有谁知道这是否可能?
如果没有,任何人都可以提出另一种方法吗?是否可以将 IIS 配置为将请求分叉到两个目标?
谢谢
更新 #1
我找到了解决方案(记录在 here),但我仍然愿意接受其他选择。
更新 #2
我喜欢 Flup 的解决方案(和理由)。他得到了赏金:) 谢谢你!
【问题讨论】:
您尝试做的事情的基础听起来有点像“中间人”,但您不想绕过所有信息,我是对的吗?如果 beep() 被调用,也许你可以注册到响应的东西 那么,当我找到自己的解决方案后,我该如何处理赏金? 也许创建一个答案就足够了,将其标记为答案并将赏金设置为您自己:) 【参考方案1】:您可以将 Web 服务配置为使用自定义操作调用程序,IOperationInvoker
。
WCF 一如既往地反序列化原始 HTTP 请求,但它不会在现有 Web 服务类上调用 Beep()
,而是调用您的调用程序。调用者执行其特殊操作,然后在原始服务上调用 Beep()
。
实现IHTTPModule
的优势在于,HTTP 的所有内容仍由原始 Web 服务的配置处理,不变。您可以在更高的抽象级别上进行分支,即在 Web 服务的接口上,在 Beep()
方法处。
在不更改现有服务类的情况下设置自定义操作调用程序的本质(这使得它变得更加困难):
实现自定义IOperationBehavior
,在其ApplyDispatchBehavior
方法中在服务的Beep()
方法上设置自定义IOperationInvoker
。
实现自定义IEndpointBehavior
,在其ApplyDispatchBehavior
方法中设置自定义IOperationBehavior
。
将这两个行为与您的IOperationInvoker
一起放在类库中并将其添加到现有服务中
然后将服务配置为使用IEndpointBehavior
。
有关调用程序位,请参见 When and where to set a custom IOperationInvoker? 和 http://blogs.msdn.com/b/carlosfigueira/archive/2011/05/17/wcf-extensibility-ioperationinvoker.aspx。
请参阅Custom Endpoint Behavior using Standard webHttpEndpoint,了解如何配置自定义端点。
【讨论】:
这听起来很完美!我今天会试一试。只要这不会以某种方式改变 Beep() 的行为(例如,神秘地改变故障内容或吞噬异常),那么我很高兴 :) 我今天晚些时候会回来奖励赏金。 像魅力一样工作。谢谢。【参考方案2】:听起来您实际上想将您的系统集成到 ESB 模式中。现在,MS 解决 ESB 问题的方法是 Biztalk。在这种情况下,Biztalk 是热核弹头坚果饼干。你不想要 Biztalk。
在此处查看lightweight alternatives的结果
【讨论】:
碰巧我们已经在考虑采用 BizTalk 作为我们的 ESB。如果我们得到它,我会考虑使用它:) 我找到了使用自定义IHttpModule
的合适解决方案,因此我不会接受 ESB 建议。对不起:|【参考方案3】:
我找到了使用自定义IHttpModule
的解决方案。请参阅下面的示例:
using System;
using System.Text;
using System.Web;
namespace ForkHandles
public class ForkHandler : IHttpModule
public void Init(HttpApplication application)
application.BeginRequest += new EventHandler(application_BeginRequest);
void application_BeginRequest(object sender, EventArgs e)
var request = ((HttpApplication)sender).Request;
var bytes = new byte[request.InputStream.Length];
request.InputStream.Read(bytes, 0, bytes.Length);
request.InputStream.Position = 0;
var requestContent = Encoding.ASCII.GetString(bytes);
// vvv
// Apply my custom logic here, using the requestContent as input.
// ^^^
public void Dispose()
这将允许我检查网络服务请求的内容并做出相应的反应。
我对其他侵入性较小的解决方案持开放态度,因为这需要更改已部署的第 3 方 Web 服务的配置。
【讨论】:
【参考方案4】:如果您想拦截发送到 T&A WCF 服务的消息,我建议您使用自定义侦听器,该侦听器可以通过在 web.cofig 中进行更改来插入服务调用。
这将是透明的。
请查找 WCF 可扩展性 - 消息检查器。
system.diagnostics>
<sources>
<source name="System.ServiceModel.MessageLogging">
<listeners>
<add name="ServiceModelMessageLoggingListener">
<filter type=""/>
</add>
</listeners>
</source>
</sources>
</system.diagnostics>
【讨论】:
有趣。与 HttpModule 方法相比,这有什么好处?这是更标准的方法吗? 请在网上搜索文章。 我有。我希望从你的个人经验中学习,但没关系。在与我的同事讨论后,我们认为我们将采用 HttpModule 方法。以上是关于挂钩到第 3 方 Web 服务 (WCF) 调用的主要内容,如果未能解决你的问题,请参考以下文章
使用 WS 安全性在 WCF .NET 中向 Java Web 服务发送请求
一步一步搭建客服系统 客户列表 - JS($.ajax)调用WCF 遇到的各种坑