【问题标题】:SOAP returns data, but C# says null responseSOAP 返回数据,但 C# 显示空响应
【发布时间】: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:Envelopesoapenv: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


【解决方案1】:

好的,我想我找到了解决这个完全相同的问题的方法。我发现要解决这个问题,必须正确配置两个主要项目。

  1. 确保在服务上设置命名空间(PeopleTools > 集成代理 > 集成设置 > 服务)。在我的项目中,我使用了一个命名空间:

    http://xmlns.oracle.com/Enterprise/EnterprisePortal/services
    
  2. 如何创建架构和它们使用的命名空间非常重要。每个模式都需要基于 PeopleSoft 返回消息的方式的特殊名称空间格式和消息格式。对于我来说,我使用了以下模式:

    请求消息架构示例: (我使用的请求消息是IS_CL_COMPLETEPERCENTAGE_REQ.V1)

        <?xml version="1.0"?> 
        <xsd:schema attributeFormDefault="unqualified" elementFormDefault="qualified" targetNamespace="http://xmlns.oracle.com/Enterprise/EnterprisePortal/services/IS_CL_COMPLETEPERCENTAGE_REQ.V1" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 
          <xsd:element name="IS_CL_COMPLETEPERCENTAGE_REQ"> 
            <xsd:complexType> 
              <xsd:sequence> 
                <xsd:element name="USER_ID" type="xsd:string"/> 
                <xsd:element name="CHECKLIST_TYPE" type="xsd:string"/> 
                <xsd:element name="CHECKLIST_ID" type="xsd:string"/> 
                <xsd:element name="CHECKLIST_INSTANCE_ID" type="xsd:integer"/> 
              </xsd:sequence> 
            </xsd:complexType> 
          </xsd:element> 
        </xsd:schema>
    

    示例响应消息架构: (我使用的响应消息是IS_CL_COMPLETEPERCENTAGE_RES.V1)

        <?xml version="1.0"?> 
        <xsd:schema attributeFormDefault="unqualified" elementFormDefault="qualified" targetNamespace="http://peoplesoft.com/IS_CL_COMPLETEPERCENTAGE_RESResponse" xmlns:tns="http://peoplesoft.com/IS_CL_COMPLETEPERCENTAGE_RESResponse" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 
          <xsd:element name="IS_CL_COMPLETEPERCENTAGE_RES"> 
            <xsd:complexType> 
              <xsd:sequence> 
                <xsd:element name="PERCENTCOMPLETE" type="xsd:integer"/> 
              </xsd:sequence> 
            </xsd:complexType> 
          </xsd:element> 
        </xsd:schema>
    

在我使用此信息发布我的 Web 服务后,SoapUI 验证了请求和响应都没有问题。

示例 SOAP 请求消息

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:is="http://xmlns.oracle.com/Enterprise/EnterprisePortal/services/IS_CL_COMPLETEPERCENTAGE_REQ.V1" xmlns:sch="http://xmlns.oracle.com/Enterprise/Tools/schemas">
   <soapenv:Header/>
   <soapenv:Body>
      <is:IS_CL_COMPLETEPERCENTAGE_REQ>
         <is:USER_ID>999999</is:USER_ID>
         <is:CHECKLIST_TYPE>GRP</is:CHECKLIST_TYPE>
         <is:CHECKLIST_ID>NEW_HIRE_CHECKLIST</is:CHECKLIST_ID>
         <is:CHECKLIST_INSTANCE_ID>0</is:CHECKLIST_INSTANCE_ID>
      </is:IS_CL_COMPLETEPERCENTAGE_REQ>
   </soapenv:Body>
</soapenv:Envelope>

示例 SOAP 响应消息

<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>
      <IS_CL_COMPLETEPERCENTAGE_RES xmlns="http://peoplesoft.com/IS_CL_COMPLETEPERCENTAGE_RESResponse">
         <PERCENTCOMPLETE>33</PERCENTCOMPLETE>
      </IS_CL_COMPLETEPERCENTAGE_RES>
   </soapenv:Body>
</soapenv:Envelope>

【讨论】:

    【解决方案2】:

    来自甲骨文 该问题已由 PT8.50.00 中的错误 ID 11560861 解决

    在 PT 8.50 脚步: A. 为回复消息重新创建架构: 1. 人员工具>集成代理>集成设置>消息。 2. 选择 COMBO_CF_EDIT_REPLY 消息。 3. 选中“包括命名空间”复选框。 4. 保存。

    B.重新生成 WSDL: 1. Peopletools>Integration Broker>Web 服务。 2. 选择 COMBO_CF_EDIT_REQUEST 服务操作。 3. 继续使用提供 Web 服务向导生成 WSDL。

    在升级到 8.50 之前,有三个解决方法选项: A. 修改 WSDL:
    1. 从 PeopleTools 生成 WSDL,然后保存到文件。 2. 通过修改回复来更新 WSDL 文件以具有条目

    替换生成的: xmlns="http://xmlns.oracle.com/Enterprise/FSCM/schema/COMBO_CF_EDIT_REPLYResponse">"

    1. 然后将 WSDL 文件读回存储库。 Peopletools>Integration Broker>Web 服务>使用 Web 服务。

      或 B. 将基于行集的消息转换为容器/部分行集消息。

    2. 要创建容器/行集部件消息,请参阅: PeopleBook:PeopleSoft 集成代理 > 管理消息>管理消息部分 PeopleBook:PeopleSoft 集成代理 > 管理消息>管理容器消息

    3. 修改服务操作以引用容器消息。

    4. 然后生成一个新的 WSDL。
    5. 修改 Handler Peoplecode 以利用 Parts 消息的方法。 请参阅:PeopleBook:PeopleCode API 参考 > 消息类> %PART% 方法

    或 C. 通过 XSLT 或 PeopleCode 转换出站响应消息以匹配 WSDL 是将实际响应 xmlns 调整为预期值的另一种方法。

    【讨论】:

      猜你喜欢
      • 2017-03-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-09-02
      • 1970-01-01
      • 2018-07-20
      相关资源
      最近更新 更多