我们有第三方供应商服务和内部服务与之沟通。一切都与我们的内部服务完美配合,但我被要求写下我们供应商服务的后备克隆。目的是能够运行我们的克隆,换出客户端,并允许我们的内部服务继续测试克隆。
到目前为止,我已经尝试了3件事,但没有一件工作。
创建一个简单的服务,引用第三方服务以获取对自定义类型的访问权限并模仿[operation Contract]
。
当我尝试与此服务通信时,我收到以下错误。
'System.ServiceModel.ActionNotSupportedException'
中出现System.ServiceModel.dll
类型的第一次机会异常
附加信息:由于EndpointDispatcher上的ContractFilter不匹配,无法在接收方处理带有Action''的消息。这可能是由于合同不匹配(发送方与接收方之间的操作不匹配)或发送方与接收方之间的绑定/安全性不匹配。检查发件人和收件人是否具有相同的合同和相同的约束(包括安全要求,例如邮件,传输,无)。
由于我们使用的是基本的http(无ssl),因此没有安全要求。配置文件的服务模型部分和服务行为类属性如下:
<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>
和服务行为
[ServiceBehavior(Name = "CloneService",
ConfigurationName = "MyClone",
InstanceContextMode = InstanceContextMode.PerCall,
AddressFilterMode = AddressFilterMode.Any)]
public class MyService : IMyService
{
一切看起来都很好,我已经到了第一个死胡同。
删除我的接口/服务合约,并直接从reference.cs文件中生成的接口继承。
当我运行此服务时,我收到以下错误
System.InvalidOperationException:操作myMethodA和myMethodB具有相同的操作()。每个操作都必须具有唯一的操作值。
在System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ActionDemuxer.Add(String action,DispatchOperationRuntime operation) 在System.ServiceModel.Dispatcher.ImmutableDispatchRuntime..ctor(DispatchRuntime dispatch) 在System.ServiceModel.Dispatcher.DispatchRuntime.GetRuntimeCore() 在System.ServiceModel.Dispatcher.ChannelDispatcher.OnOpened() 在System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan超时) 在System.ServiceModel.ServiceHostBase.OnOpen(TimeSpan超时) 在System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan超时) 在Microsoft.Tools.SvcHost.ServiceHostHelper.OpenService(ServiceInfo info)
看一下这个方法的生成界面,它们都用以下属性修饰:
[System.ServiceModel.OperationContractAttribute(Action="", ReplyAction="*")]
我对msdn的理解是,WCF默认添加模式<namespace>/<service>/<operation>[Response]
的唯一操作。
如果我尝试将操作设置为*
,那么我可以点击服务(正如预期的那样使用catch all / unmatched message handler),但我无法点击特定的方法。
尽管如此,手动使所有操作都是唯一的(并符合上述模式),会出现此错误:
客户端配置中的合同“IMyService”与服务合同中的名称不匹配,或者此合同中没有有效的方法。 ...
我已经在服务合同中明确定义了方法,并且已经到了第二个死胡同。
使用wsdl.exe工具从wsdl生成服务。我按照this SO post中的说明生成了一个接口并从中继承。
我还尝试使用clientWsdl.wsdl /l:CS /server
命令并按照this帖子中的说明生成服务本身。
在整理生成的代码并运行它之后,我又回到了原来的错误:
System.ServiceModel.dll中出现'System.ServiceModel.ActionNotSupportedException'
类型的第一次机会异常
附加信息:由于EndpointDispatcher上的ContractFilter不匹配,无法在接收方处理带有Action''的消息。这可能是由于合同不匹配(发送方与接收方之间的操作不匹配)或发送方与接收方之间的绑定/安全性不匹配。检查发件人和收件人是否具有相同的合同和相同的约束(包括安全要求,例如邮件,传输,无)。
在每次尝试时,我都仔细检查了所有配置设置,并在每个阶段更新了合同。
在这个阶段,我想知道它是否可能。
答案 0 :(得分:1)
您是否能够使用WCF模仿服务?我发现自己处于类似的情况,我的任务是编写一些集成测试,我们的方法调用供应商的Web服务。我宁愿利用Moq编写适当的单元测试,但我受到以下约束:1)不允许更改我正在测试的方法的签名,2)除了Web服务本身之外什么都不知道,除了我们发送给服务的内容及其预期的响应。
@ jparram的建议是我的下一个方法。
注意:我本来希望将此作为评论发布,因为我没有回答你的问题。
答案 1 :(得分:0)
如果我理解你的场景,我会创建包装服务来决定要调用哪个服务。这听起来就像你想要用Scenario 1做的那样。所以,你的客户端总是会调用你的包装服务,你的包装服务会将输入映射到第三方服务或备份服务所需的输入。
您收到的错误听起来像代理客户端的生成中的问题,其中“Action”未被映射。查看已知工作配置中生成的代理代码,并将其与方案1中的代码进行比较。
修改的 比较生成的服务代理客户端和“真实”服务。关于行动 =“”的投诉可能是由于:
[System.ServiceModel.OperationContractAttribute(Action="", ReplyAction="")]
在您的客户端上没有映射到相应的操作。