【发布时间】:2012-08-31 22:19:39
【问题描述】:
我的 C# 应用程序只给我 SOAP 调用的空结果。
我们使用 SOAP Web 服务公开了一些 PeopleSoft ERP 数据。
我正在从 Visual Studio 2012 ASP.NET C# 应用程序访问此 SOAP 服务。我有一个名为 CampusDirectoryService 的服务参考,它是使用 ERP 生成的 WSDL 构建的。
这是 C# 代码:
var service = new CampusDirectoryService.TEST_PortTypeClient();
var input = new CampusDirectoryService.InputParameters();
input.First_Name = FirstNameBox.Text;
input.Last_Name = LastNameBox.Text;
var returnData = service.TEST_OP(input);
问题是returnData 始终为空。通过 Wireshark,我确认我实际上得到了带有数据的有效 SOAP 响应。 returnData 不应为空。
我也通过soapUI 确认了来自 SOAP 服务的正确有效结果。提交与 .NET 发送的完全相同的 SOAP 请求(我从 Wireshark 中复制了它),我得到了预期的结果。
这是 SOAP 请求:
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<InputParameters xmlns="http://xmlns.oracle.com/Enterprise/Tools/schemas">
<Last_Name xmlns="">cambre</Last_Name>
<First_Name xmlns="">aren</First_Name>
</InputParameters>
</s:Body>
</s:Envelope>
这是 SOAP 响应,ReturnID 元素内的一些内部数据被混淆或删除:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soapenv:Body>
<root xmlns="http://peoplesoft.com/rootResponse">
<ReturnID>
<PRF_Name>Cambre,Aren</PRF_Name>
<Camp_Email>valid@email.com</Camp_Email>
</ReturnID>
</root>
</soapenv:Body>
</soapenv:Envelope>
TEST_OP方法的返回类型是CampusDirectoryService.rootReturnID[]。
为什么returnData 总是为空?
更新 根据评论,我使用soapUI 验证了这些消息。它对这条消息的回应大喊大叫:
第 -1 行:缺少名称为 [{http://xmlns.oracle.com/Enterprise/Tools/schemas}root] 的消息部分
这是响应的 XSD:
<?xml version="1.0" encoding="utf-8"?>
<xs:schema targetNamespace="http://xmlns.oracle.com/Enterprise/Tools/schemas" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="root">
<xs:complexType>
<xs:sequence>
<xs:element maxOccurs="unbounded" name="ReturnID">
<xs:complexType>
<xs:sequence>
<xs:element name="PRF_Name" type="xs:string" />
<xs:element name="Camp_Email" type="xs:string" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
XSD 是应该验证 soapenv:Body 内部的内容,还是应该验证整个响应,包括 soapenv:Envelope 和 soapenv:Body 元素?看起来soapUI 希望XSD 验证整个响应,而不仅仅是soapenv:Body 中的内容。
这是 WSDL:
<wsdl:definitions name="TEST.1" targetNamespace="http://xmlns.oracle.com/Enterprise/HCM/schemas/TEST.1" xmlns:U_IT_CAMDIR_REQUEST_MSG.VERSION_1="http://xmlns.oracle.com/Enterprise/Tools/schemas" xmlns:U_IT_CAMDIR_RESPONSE_MSG.VERSION_1="http://xmlns.oracle.com/Enterprise/Tools/schemas" xmlns:plnk="http://schemas.xmlsoap.org/ws/2003/05/partner-link/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="http://xmlns.oracle.com/Enterprise/HCM/schemas/TEST.1" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:wsp="http://schemas.xmlsoap.org/ws/2002/12/policy">
<wsp:UsagePolicy wsdl:Required="true"/>
<plnk:partnerLinkType name="TEST_PartnerLinkType">
<plnk:role name="TEST_Provider">
<plnk:portType name="tns:TEST_PortType"/>
</plnk:role>
</plnk:partnerLinkType>
<wsdl:types>
<xsd:schema elementFormDefault="qualified" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:import namespace="http://xmlns.oracle.com/Enterprise/Tools/schemas" schemaLocation="U_IT_CAMDIR_REQUEST_MSG.VERSION_1.xsd"/>
<xsd:import namespace="http://xmlns.oracle.com/Enterprise/Tools/schemas" schemaLocation="U_IT_CAMDIR_RESPONSE_MSG.VERSION_1.xsd"/>
</xsd:schema>
</wsdl:types>
<wsdl:message name="U_IT_CAMDIR_REQUEST_MSG.VERSION_1">
<wsdl:documentation>People Directory</wsdl:documentation>
<wsdl:part element="U_IT_CAMDIR_REQUEST_MSG.VERSION_1:InputParameters" name="parameter"/>
</wsdl:message>
<wsdl:message name="U_IT_CAMDIR_RESPONSE_MSG.VERSION_1">
<wsdl:documentation>People Directory</wsdl:documentation>
<wsdl:part element="U_IT_CAMDIR_RESPONSE_MSG.VERSION_1:root" name="parameter"/>
</wsdl:message>
<wsdl:portType name="TEST_PortType">
<wsdl:operation name="TEST_OP">
<wsdl:documentation>TEST</wsdl:documentation>
<wsdl:input message="tns:U_IT_CAMDIR_REQUEST_MSG.VERSION_1" name="U_IT_CAMDIR_REQUEST_MSG.VERSION_1"/>
<wsdl:output message="tns:U_IT_CAMDIR_RESPONSE_MSG.VERSION_1" name="U_IT_CAMDIR_RESPONSE_MSG.VERSION_1"/>
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="TEST_Binding" type="tns:TEST_PortType">
<soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
<wsdl:operation name="TEST_OP">
<soap:operation soapAction="TEST_OP.v1" style="document"/>
<wsp:Policy wsu:Id="UsernameTokenSecurityPolicyPasswordOptional" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<wsp:ExactlyOne>
<wsp:All>
<wsse:SecurityToken wsp:Usage="wsp:Required" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<wsse:TokenType>wsse:UserNameToken</wsse:TokenType>
<Claims>
<SubjectName MatchType="wsse:Exact"/>
<UsePassword wsp:Usage="wsp:Optional"/>
</Claims>
</wsse:SecurityToken>
</wsp:All>
</wsp:ExactlyOne>
</wsp:Policy>
<wsdl:input name="U_IT_CAMDIR_REQUEST_MSG.VERSION_1">
<soap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" use="literal"/>
</wsdl:input>
<wsdl:output name="U_IT_CAMDIR_RESPONSE_MSG.VERSION_1">
<soap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" use="literal"/>
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="TEST">
<wsdl:documentation>TEST</wsdl:documentation>
<wsdl:port binding="tns:TEST_Binding" name="TEST_Port">
<soap:address location="http://domainname.com/longurltoSOAPservicehere"/>
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
【问题讨论】:
-
您是否使用了 soapUI 的验证功能(右键单击请求或响应 > 验证 (Alt+V))来确保请求和响应根据 WSDL 定义有效?
-
xmlns 看起来有点不对劲:请求有一个用于 InputParameters 的 URL,其中的元素为空白,然后响应有一个完全不同的 URL,它用于所有元素。当然,这可能是您的 WSDL 定义的,但它确实看起来很奇怪。
-
@TimS.:谢谢。我在响应中收到此验证错误:
line -1: Missing message part with name [{http://xmlns.oracle.com/Enterprise/Tools/schemas}root]。将进一步调查。 -
@TimS.:我添加了 XSD。这可能有助于澄清事情。
-
@TimS.:我认为你关于命名空间的理论是正确的。响应中引用的 XMLNS 在 WSDL 中的任何地方都没有提及。
标签: c# xml web-services soap peoplesoft