我们使用.NET 4.x WCF来使用JAX-WS服务。通过“添加服务引用”从WSDL和XSD生成的代理生成可以正确调用服务的代码。但是,服务响应使用未在XSD中定义的根元素名称。代理返回null结果,可能是因为元素名称未被识别,因此忽略响应包络的其余部分。
SOAP响应如下所示。请注意,正文中的根元素名为txLife22814Type
:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<s:Header xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" />
<soapenv:Body>
<ns3:txLife22814Type xmlns:ns3="http://ACORD.org/Standards/Life/2" xmlns:ns2="http://dtcc.com/lnapm/service/">
<ns3:TXLife>
...snip...
</ns3:TXLife>
</ns3:txLife22814Type>
</soapenv:Body>
</soapenv:Envelope>
XSD的相关部分如下所示。请注意,根元素的名称为Tx22814
,并且没有与txLife22814Type
complexType关联的TXLife_22814_Type
:
<xs:schema xmlns="http://ACORD.org/Standards/Life/2" xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="http://ACORD.org/Standards/Life/2" elementFormDefault="qualified" attributeFormDefault="unqualified">
<xs:element name="Tx22814" type="TXLife_22814_Type"/>
<xs:element name="Tx22815" type="TXLife_22815_Type"/>
<xs:element name="Tx22816" type="TXLife_22816_Type"/>
<xs:complexType name="TXLife_22814_Type">
<xs:sequence>
<xs:element name="TXLife" type="TXLife_IPT_Type"/>
</xs:sequence>
</xs:complexType>
其余的响应与XSD匹配就好了。 (我没有发布完整的WSDL和XSD,因为它们非常庞大,数百行。)
在发送方,操作请求采用相同类型(TXLife_22814_Type
)作为输入参数(实际上它是由服务修改的byref),调用的WSDL引用正确的XSD名称( Tx22814
),它有效。
我尝试将第二个根添加到XSD,它映射到相同的类型:
<xs:element name="txLife22814Type" type="TXLife_22814_Type"/>
这导致请求失败,这让我感到惊讶。我想知道WCF是否不能消除类型的歧义,尽管我希望在WSDL中明确使用Tx22814
名称应该处理它。 WSDL(为了便于阅读以仅显示相关操作而进行了大量编辑)看起来像这样。这里感兴趣的操作或“消息”是isProducerTrainedRequest
:
<wsdl:definitions ...snip... >
<wsdl:types>
<xsd:schema targetNamespace="http://dtcc.com/lnapm/service/">
<xsd:import namespace="http://ACORD.org/Standards/Life/2" schemaLocation="DTCC_PM_ACCORD_V2.28.xsd"/>
<xsd:element name="MessageHeader">
... snip ...
</xsd:element>
</xsd:schema>
</wsdl:types>
<wsdl:message name="isProducerTrainedRequest">
<wsdl:part element="ns1:Tx22814" name="Tx22814"/>
</wsdl:message>
<wsdl:message name="isProducerTrainedResponse">
<wsdl:part element="ns1:Tx22814" name="Tx22814Response"/>
</wsdl:message>
我编写了一个AfterReceiveReply拦截器,并在受损的标签上进行了字符串替换,然后代理的其余部分工作,但这显然是一个黑客,我们宁愿不使用生产代码。
我们不拥有该服务。服务提供商没有其他.NET使用者。他们声称他们所有基于Java的客户端都没有问题。 (也许JAX-WS或Java通常假设某种元素名称装饰?或者忽略它?)
有没有人见过这个?有没有人有办法解决吗?有没有办法在Reference.cs中装饰一些东西来翻译或映射元素名称,或者沿着那些行?我不是SOAP或XML专家;我是否误解了SOAP和/或XSD元素命名规则?是否可以更改XSD以满足请求和响应?