我们有一个ASMX服务,我们的客户端通过Perl API使用它。目前我们正在将ASMX服务转换为WCF但我们的客户端无法向我们的WCF服务发送请求。
当我们询问客户时,他们说他们只是简单地将数据对象作为XML传递给SOAP而且他们不依赖于我们的服务代理,但是在日志中我们看到下面的错误消息。
由于EndpointDispatcher上的ContractFilter不匹配,无法在接收方处理“带有Action'的消息。这可能是由于合同不匹配(发送方和接收方之间的操作不匹配)或绑定/发送方和接收方之间的安全性不匹配。检查发送方和接收方是否具有相同的合同和相同的绑定“
请告知我们如何解决/解决此问题!!!
修改
客户端发送给我们的XML。这在他们发送到我们的ASMX时正常工作:
<?xml version="1.0" encoding="utf-8">
<soap:envelope xmlns:soap="reference url" xmlns:xsi="reference url">
xmlns:xsd="http://www.w3.org/2001/xmlschema">
<SOAP:body>
<contractname xmlns="http://tempuri.org/">
<xml>
<foo>
<fooid>1</fooid>
</foo>
</xml>
<contractname>
</soap:body>
</soap:envelope>
但是当我通过WCF测试客户端运行我的WCF服务时,我看到下面的XML测试客户端正在发送到我的服务..
<S:envelope xmlns:="http://schemas.xmlsoap.org/soap/envelope/">
<S:Header>
<Action s: mustUnderstand="1" xmlns="http://schemas.microsoft.com/ws/2005/05/addressing/none">http://tempuri.org/contractname
</s:header>
<S:body xmlns xsi="http://www.w3.org/2001/xmlschema-instance" xmlns:xsd="http://www.w3.org/2001/xmlschema">
<contractname xmlns="http://tempuri.org/">
<xml>
<foo>
<fooid>1</fooid>
</foo>
</xml>
</contractname> etc..
如何配置我的WCF以便它接受客户端发送给我们的XML ..
我的服务合同:(除了我在下面尝试过的,我尝试过Tom在他的回复中提到的解决方案)
[ServiceContract(Namespace="http://tempuri.org"),xmlserializerformat]
public interface IStockService
{
[OperationContract(Action=@"http://tempuri.org/GetStockValue",Name="GetStockValue")]
int GetStockValue(string stockSymbol);
}
请注意,我们的客户不依赖于我们的WSDL。当最初启动此握手时,我们团队的开发人员向客户端发送了一个示例XML请求,因此我相信他们可能会编写Perl脚本来生成完全类似于我们团队发送的XML,因此我应该要求他们修改脚本以匹配当前脚本我们期待的。
我是否可以修改我的服务合同,我们的服务将接受他们传递的相同XML。
答案 0 :(得分:0)
如果您的客户不依赖元数据来使用您的服务,那么他们就会对您的服务进行非常脆弱的集成。如果你改变了服务,他们认为会发生什么?
无论如何,您可以尝试的第一件事是通过basicHttpBinding公开您的服务,它将创建您的端点作为SOAP 1.1服务,与asmx使用的SOAP相同。
谷歌搜索如何使wcf服务看起来像.asmx 会返回许多结果,包括:http://blogs.msdn.com/b/codejunkie/archive/2008/06/12/how-to-create-a-wcf-service-for-asmx-client-without-changing-the-client.aspx
[ServiceContract] [XmlSerializerFormat(Use = OperationFormatUse.Literal, Style = OperationFormatStyle.Document)] public interface IStockService { [OperationContract(Action="http://tempuri.org/GetStockValue", ReplyAction="http://tempuri.org/GetStockValue")] int GetStockValue(string stockSymbol); [OperationContract(Action="http://tempuri.org/GetCompanyDetails", ReplyAction="http://tempuri.org/GetCompanyDetails")] Company GetCompanyDetails(string stockSymbol); }
一旦我们对WCF服务接口进行了上述更改,现在就是 客户端应该能够与WCF服务无缝通信。
在此过程中需要注意的事项。
- 使用basicHttpBinding进行服务绑定
- 删除MEX端点以启用Windows身份验证
- 使用XmlSerializerFormatAttribute启用正确的消息传递格式
- 使用Action / ReplyAction参数来提供名称空间支持
根据评论进行编辑
我注意到您的服务存在潜在问题,表现在您的WCFClient xml:
<contractname xmlns="tempuri.org">
应该是
<contractname xmlns="http://tempuri.org">
您是否可以检查服务定义代码以确保正确设置OperationContract的Action参数。事实上,你可以发布你的服务代码吗?
ALSO :这里有一个更深层次的问题我认为值得讨论,它与api /服务提供商和消费者之间关系中必须存在的未说出口的礼仪有关。
通过提供api /服务,提供商默认同意避免不必要的或不合理的突破性更改。
通过使用该服务,消费者默认同意跟踪和响应服务中的合理的或必要的更改。
听起来你的消费者在这种情况下不尊重“协议”。期望服务端点永远不会改变是一种不合理的期望。
虽然很可能更改您的服务以适应客户端,但从技术角度来看,客户端更容易更改以适应服务,因此服务元数据如WSDL。