有人可以对这种行为有所了解吗?看起来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;
}
答案 0 :(得分:10)
当SOAP主要是以rpc为导向的问题时,这些问题经常出现。没有特定的顺序来确定哪个部分是函数(操作)的结果。 Delphi自己的导入器曾经[并且可能仍然会]通过部件名称识别'结果'。你可以(可以??)指定一个逗号分隔的名称列表来使用。如果没有任何部分与名称相匹配,那么如果只有一个部分,那就是结果。
SOAP规范。最终确实包括了解决这个问题的补充。在您的情况下,相关的一个是'parameterOrder'属性(还有rpc:实际SOAP数据的结果)。但是,您几乎看不到使用该属性的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逻辑生成parameterOrder。
干杯,
布诺
PS:(*)更新WSDL生成逻辑以发出parameterOrder也很容易。自从我参与该代码以来,这是一段漫长的时间,但它相当直接(如果我没记错的话):