SOAP不一致性?Delphi 2010(Win32)服务器和.NET客户端交换“输出参数”和“结果”。

5

请问有人能解释一下这个行为吗?看起来Delphi SOAP将函数结果设置为最后一个参数,但WSDL.exe读取第一个参数作为函数结果。

我在Delphi SOAP服务中有以下方法,其中结果字符串用于基本错误处理:

function LoadCustomer(CustomerID: Double; out CustomerName: String): String;

生成的WSDL如下所示:
<message name="LoadCustomer2Request">
  <part name="CustomerID" type="xs:double"/>
</message>
<message name="LoadCustomer2Response">
  <part name="CustomerName" type="xs:string"/>
  <part name="return" type="xs:string"/>
</message>

由于某种原因,WSDL.exe生成了以下C#代码,其中交换了CustomerName和'Result'字符串:
public string LoadCustomer(double CustomerID, out string @return) {
        WindowsFormsApplication1.ServiceReference1.LoadCustomerRequest inValue = new WindowsFormsApplication1.ServiceReference1.LoadCustomerRequest();
        inValue.CustomerID = CustomerID;
        WindowsFormsApplication1.ServiceReference1.LoadCustomerResponse retVal = ((WindowsFormsApplication1.ServiceReference1.ISKiWebInterface)(this)).LoadCustomer(inValue);
        @return = retVal.@return;
        return retVal.CustomerName;
    }
1个回答

10
当SOAP主要是面向rpc时,经常会出现这样的问题。没有特定的顺序来确定哪一部分是函数(操作)的结果。Delphi自己的导入程序过去曾经 [可能仍在使用?] 通过部件名称来识别“result”。您可以(可以吗?)指定一个逗号分隔的名称列表来使用。如果没有部件与名称匹配,则如果有单个输出,则为结果。
SOAP规范最终包括了添加以解决此问题的内容。您的情况中相关的是“parameterOrder”属性(实际SOAP数据也有rpc:result)。但是,几乎不会看到使用该属性的WSDL。但是,我相信WSDL.EXE确实会注意到该属性。您可以在此处了解有关parameterOrder的更多信息:

http://www.w3.org/TR/wsdl#_parameter

我建议您将 Delphi 生成的 WSDL 文件保存到文件中,并更新该文件以包括 parameterOrder 属性(*)。例如,在您提供的情况下,您需要查找映射到接口的 portType 并按以下方式更新操作:
  <portType name="InterfaceName">
    <operation name="LoadCustomer" parameterOrder="CustomerId, CustomerName">
      <input message="tns:LoadCustomer2Request"/>
      <output message="tns:LoadCustomer2Response"/>
    </operation>
  </portType>

然后,使用WSDL.EXE导入更新后的WSDL应该会得到类似以下内容:

  public string LoadCustomer(out string CustomerName, double CustomerID) {
    object[] results = this.Invoke("LoadCustomer", new object[] {
                CustomerID});
    CustomerName = ((string)(results[1]));
    return ((string)(results[0]));
  }

您还应该在方法上方看到以下属性,以确认'return'确实是结果:

 [return: System.Xml.Serialization.SoapElementAttribute("return")]

我建议打开一个QC请求,要求参数顺序由Delphi的WSDL逻辑生成。
祝好,
Bruneau
PS:(*) 更新WSDL生成逻辑以发出parameterOrder也很容易。我已经很久没有接触那段代码了,但如果我没记错的话,这是相当简单的。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接