简体   繁体   English

您可以模仿WCF中的现有服务吗?

[英]Can you mimic an existing service in WCF?

We have a 3rd party vendor service and an in-house service to communicate with it. 我们有一个第三方供应商服务和一个内部服务与之通信。 Everything works perfectly with our in-house service, but I've been asked to write a fall back clone of our vendor's service. 一切都可以与我们的内部服务完美配合,但是我被要求写一个供应商服务的后备克隆。 The intention is to be able to run up our clone, swap-out the client end-point and allow our in-house service to continue testing against the clone. 目的是能够运行我们的克隆,换出客户端端点,并允许我们的内部服务继续针对该克隆进行测试。

Is it possible to recreate/mimic a service such that an existing client can communicate with it (without modification) as if it were the original service? 是否可以重新创建/模仿服务,以便现有客户端可以与该服务进行通信(无需修改),就好像它是原始服务一样?

So far I've tried 3 things and none of them work. 到目前为止,我已经尝试了3种方法,但均无效果。

1st approach 第一种方法

Create a simple service, reference the 3rd party service to gain access to the custom types and mimic the [operation Contract] 's. 创建一个简单的服务,引用第三方服务以获得对自定义类型的访问并模仿[operation Contract]

When I try to communicate with this service I get the following error. 当我尝试与此服务进行通信时,出现以下错误。

A first chance exception of type 'System.ServiceModel.ActionNotSupportedException' occurred in System.ServiceModel.dll Additional information: The message with Action '' cannot be processed at the receiver, due to a ContractFilter mismatch at the EndpointDispatcher. 类型的第一次机会异常'System.ServiceModel.ActionNotSupportedException'发生在System.ServiceModel.dll其他信息:与动作“”的消息不能在接收器进行处理,由于在一个EndpointDispatcher ContractFilter失配。 This may be because of either a contract mismatch (mismatched Actions between sender and receiver) or a binding/security mismatch between the sender and the receiver. 这可能是由于合同不匹配(发送方和接收方之间的操作不匹配)或发送方和接收方之间的绑定/安全不匹配造成的。 Check that sender and receiver have the same contract and the same binding (including security requirements, eg Message, Transport, None). 检查发送方和接收方是否具有相同的合同和相同的绑定(包括安全要求,例如,消息,传输,无)。

There is no security requirements as we are using basic http (no ssl). 由于我们使用的是基本http(没有ssl),因此没有安全要求。 The service model portion of the config file and the service behaviour class attributes are below: 配置文件的服务模型部分和服务行为类属性如下:

<system.serviceModel>
    <bindings>
      <basicHttpBinding>
        <binding name="SimpleBinding" />
      </basicHttpBinding>
    </bindings>
    <services>
      <service behaviorConfiguration="cloneBehavior" name="MyClone">
        <endpoint address="" binding="basicHttpBinding" bindingConfiguration="SimpleBinding"
          contract="MyService.IMyService" />
        <host>
          <baseAddresses>
            <add baseAddress="http://localhost/clone/" />
          </baseAddresses>
        </host>
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior name="cloneBehavior">
          <serviceMetadata httpGetEnabled="True" httpGetUrl="http://localhost/clone/mex" />
          <serviceDebug includeExceptionDetailInFaults="False" />
        </behavior>
      </serviceBehaviors>
    </behaviors>
</system.serviceModel>

and the service behaviour 和服务行为

[ServiceBehavior(Name = "CloneService", 
    ConfigurationName = "MyClone", 
    InstanceContextMode = InstanceContextMode.PerCall, 
    AddressFilterMode = AddressFilterMode.Any)]
public class MyService : IMyService
{

Everything looks good and I have come to my first dead end. 一切看起来都很好,我走到了第一个死胡同。

2nd approach 第二种方法

Get rid of my interface/service contract and inherit directly from the interface generated in the reference.cs file. 摆脱我的界面/服务合约,直接从reference.cs文件中生成的界面继承。

When I run this service up, I get the following error 当我运行此服务时,出现以下错误

System.InvalidOperationException: The operations myMethodA and myMethodB have the same action (). System.InvalidOperationException:操作myMethodA和myMethodB具有相同的操作()。 Every operation must have a unique action value. 每个操作必须具有唯一的动作值。

at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ActionDemuxer.Add(String action, DispatchOperationRuntime operation) at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime..ctor(DispatchRuntime dispatch) at System.ServiceModel.Dispatcher.DispatchRuntime.GetRuntimeCore() at System.ServiceModel.Dispatcher.ChannelDispatcher.OnOpened() at System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout) at System.ServiceModel.ServiceHostBase.OnOpen(TimeSpan timeout) at System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout) at Microsoft.Tools.SvcHost.ServiceHostHelper.OpenService(ServiceInfo info) 在System.ServiceModel.Dispatcher.ImmutableDispatchRuntime..ctor(DispatchRuntime调度)在System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ActionDemuxer.Add(字符串操作,DispatchOperationRuntime操作)在System.ServiceModel.Dispatcher.DispatchRuntime.GetRuntimeModel() Microsoft的System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan超时)处的.Dispatcher.ChannelDispatcher.OnOpened()处于Microsoft的System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan超时)处的System.ServiceModel.ServiceHostBase.OnOpen(TimeSpan超时)处的。 .Tools.SvcHost.ServiceHostHelper.OpenService(ServiceInfo信息)

Taking a look at the generated interface for this method, they are all decorated with the following attribute: 看一下此方法生成的接口,它们都用以下属性修饰:

[System.ServiceModel.OperationContractAttribute(Action="", ReplyAction="*")]

My understanding from msdn is that WCF defaults to adding a unique action of the pattern <namespace>/<service>/<operation>[Response] . 我从msdn的理解是WCF默认添加<namespace>/<service>/<operation>[Response]模式的唯一动作。

If I try setting the action to * then I can hit the service (as expected with the catch all / unmatched message handler), but I can't hit a specific method. 如果我尝试将操作设置为*那么我可以使用该服务(如catch all / unmatched message handler所期望的那样),但无法使用特定方法。

Nevertheless, manually making all the actions unique (and conforming to the above pattern), give this error: 但是,手动使所有动作唯一(并符合上述模式),会出现此错误:

The contract 'IMyService' in client configuration does not match the name in service contract, or there is no valid method in this contract. 客户端配置中的合同“ IMyService”与服务合同中的名称不匹配,或者该合同中没有有效的方法。 ...

I have clearly defined methods in the service contract and have come to a second dead end. 我已经在服务合同中明确定义了方法,并且陷入了第二个死胡同。

3rd approach 第三种方法

Using the wsdl.exe tool to generate a service from the wsdl. 使用wsdl.exe工具从wsdl生成服务。 I followed the instructions from this SO post to generate an interface and inherit from it. 我按照 SO帖子中的说明生成了一个接口并从中继承。

I've also tried generating the service itself by using the clientWsdl.wsdl /l:CS /server command and following the instructions in this post. 我也试着使用产生服务本身clientWsdl.wsdl /l:CS /server的命令,并按照说明这个职位。

After tidying up the generated code and running it up, I'm back to my original error: 整理生成的代码并运行之后,我回到了原来的错误:

A first chance exception of type 'System.ServiceModel.ActionNotSupportedException' occurred in System.ServiceModel.dll Additional information: The message with Action '' cannot be processed at the receiver, due to a ContractFilter mismatch at the EndpointDispatcher. 'System.ServiceModel.ActionNotSupportedException'发生了类型为'System.ServiceModel.ActionNotSupportedException'第一次机会异常。其他信息:由于EndpointDispatcher上的ContractFilter不匹配,因此无法在接收方处理带有动作''的消息。 This may be because of either a contract mismatch (mismatched Actions between sender and receiver) or a binding/security mismatch between the sender and the receiver. 这可能是由于合同不匹配(发送方和接收方之间的操作不匹配)或发送方和接收方之间的绑定/安全不匹配造成的。 Check that sender and receiver have the same contract and the same binding (including security requirements, eg Message, Transport, None). 检查发送方和接收方是否具有相同的合同和相同的绑定(包括安全要求,例如,消息,传输,无)。

At each attempt I have double checked all the config settings and updated the contract at each stage. 每次尝试时,我都会仔细检查所有配置设置,并在每个阶段更新合同。

At this stage I'm wondering if it's even possible. 在这个阶段,我想知道是否有可能。

Were you ever able to mimic the service using WCF? 您曾经能够使用WCF模仿服务吗? I find myself in a similar situation where I've been tasked to write some integration tests where our method makes a call to a vendor's web service. 我发现自己处在类似的情况下,我受命编写一些集成测试,其中我们的方法调用了供应商的Web服务。 I would have preferred to leverage Moq to write proper unit tests, but I'm constrained by 1) not being allowed to change the signature of the method that I'm testing, and 2) not really knowing anything about the web service itself except for what we send to the service and its expected response. 我本来希望利用Moq编写适当的单元测试,但是我受到以下限制:1)不允许更改我正在测试的方法的签名,以及2)除了对Web服务本身一无所知我们发送给服务的内容及其预期的响应。

@jparram's suggestion was my next approach. @jparram的建议是我的下一个方法。

Note: I would have preferred to have posted this as a comment seeing that I'm not really answering your question. 注意:如果希望我没有真正回答您的问题,我希望将其发布为评论。

If I understand your scenario, I would create wrapper service that decides which service to call. 如果了解您的情况,我将创建包装器服务,该服务决定要调用的服务。 It sounds like that's what you want to do with Scenario 1. So, your client would always be calling your wrapper service, and your wrapper service would map the inputs to the required inputs of your 3rd party service or your back up service. 听起来这就是您要对方案1进行的处理。因此,您的客户端将始终调用包装程序服务,并且包装程序服务会将输入映射到您的第三方服务或备份服务的所需输入。

The error you received sounds like an issue in the generation of the proxy client where the "Action" is not getting mapped. 您收到的错误听起来像是代理客户端的生成中的一个问题,其中未映射“操作”。 Take a look at the generated proxy code from a known working configuration and compare it to what is in your scenario 1. 查看从已知工作配置生成的代理代码,并将其与方案1中的内容进行比较。

Edit Compare the generated proxy client of your service and the 'real' service. 编辑比较生成的服务和“真实”服务的代理客户端。 The complaint about the Action = "" is probably due to the: 有关Action =“”的投诉可能是由于以下原因:

[System.ServiceModel.OperationContractAttribute(Action="", ReplyAction="")]

On your client not getting mapped to the corresponding operation. 在您的客户端上没有被映射到相应的操作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM