挂钩第三方Web服务(WCF)调用

时间:2013-03-14 16:10:10

标签: asp.net wcf iis integration httphandler

在我的工作场所,我们正在升级时间和出勤设置。目前,我们拥有员工用于办理入住和退房的实体终端。这些终端通过Web服务呼叫与第三方T& A系统通信。

关于T& A网络服务:

  • 在IIS 6上托管
  • 与WCF通过HTTP进行通信
  • 我们只对其中一种曝光方法感兴趣(我们称之为 Beep()

我需要做什么:

  • 保留原有的T& A系统,不受影响
  • 编写一个自定义服务 Beep()
  • 的调用作出反应

所以,基本上,我需要捎带所有对 Beep()的调用,但我不确定最佳方法是什么。

已经考虑过的事情:

  1. 编写一个自定义Web服务,该服务实现与T& A服务完全相同的合同,并将所有终端定向到该自定义服务。我的想法是,我可以从我的自定义服务调用原始的T& A服务,以及应用所需的任何其他逻辑。
    • 这对我来说似乎过于侵略,而且似乎风险不大。我们希望尽可能不修改原始系统。
  2. 编写自定义HTTP处理程序以拦截对原始T& A服务的调用。
    • 我们实际上已经在内部完成了类似的工作,但我们的实现采用原始的HttpRequest,提取内容,调用自定义服务,最后根据原始请求创建 new HttpRequest以便原始Web服务调用 Beep()
    • 我不喜欢这种方法,原来的HttpRequest丢失了。是的,创建了第二个(假设相同的)请求,但我对HttpRequests了解不足以保证这是安全的。
  3. 我更喜欢选项2,但它仍然不完美。理想情况下,我们不需要销毁原始的HttpRequest。有谁知道这是否可行?

    如果没有,有人可以提出另一种方法吗?可以将IIS配置为将请求分叉到两个目的地吗?

    由于

    更新#1

    我找到了一个解决方案(记录为here),但我仍然愿意接受其他选择。

    更新#2

    我喜欢flup的解决方案(和理由)。他得到赏金:)谢谢flup!

4 个答案:

答案 0 :(得分:1)

您可以将Web服务配置为使用自定义操作调用程序IOperationInvoker

WCF一如既往地反序列化原始HTTP请求,但不是在现有Web服务类上调用Beep(),而是调用您的调用者。调用者做了特殊的事情,然后在原始服务上调用Beep()

实施IHTTPModule的优势在于,所有HTTP仍然由原始Web服务的配置处理,不变。您可以使用Beep()方法在更高的抽象级别上,即在Web服务的界面上进行分离。

设置自定义操作调用程序而不更改现有服务类(这使得更难)的细节:

  • 实施自定义IOperationBehavior,在其IOperationInvoker方法中为服务的Beep()方法设置自定义ApplyDispatchBehavior
  • 实施自定义IEndpointBehavior,在其IOperationBehavior方法中设置自定义ApplyDispatchBehavior
  • 将这两项行为与您的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

答案 1 :(得分:0)

听起来您希望将系统集成到ESB模式中。现在,ESB问题的MS解决方案是Biztalk。 Biztalk是这种情况下的热核弹头坚果饼干。你不想要Biztalk。

查看lightweight alternatives

的结果

答案 2 :(得分:0)

我找到了使用自定义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()
        {
        }
    }
}

这将允许我检查Web服务请求的内容并相应地做出反应。

我对其他可能侵入性较小的解决方案持开放态度,因为这需要更改已部署的第三方Web服务的配置。

答案 3 :(得分:0)

如果你想拦截消息到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>