Кто-то мог пролить некоторый свет на это поведение? Это похоже на 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 и 'Результата':
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;
}
Когда SOAP был в основном ориентирован на rpc, такие вопросы возникали часто. Нет конкретного порядка определения, какая часть является результатом функции (операции). Собственный импортер Delphi, использовавшийся для [и, возможно, до сих пор использует???] идентификации "результата" по названию части. И можно (можно???) указать список имен, разделенных запятыми. Если ни одна из частей не совпадает с названиями, то, если есть одно, то это результат.
Спецификация SOAP. в конечном итоге включала в себя дополнения для решения этой проблемы. Соответствующим в вашем случае является атрибут 'parameterOrder' (есть также rpc:result для фактических данных SOAP). Однако, вы вряд ли увидите WSDL, которые используют этот атрибут. Но я считаю, что WSDL.EXE действительно обращает внимание на этот атрибут. Вы можете узнать больше о parameterOrder здесь:
http://www.w3.org/TR/wsdl#_parameter
Я бы посоветовал вам сохранить WSDL, сгенерированную Delphi, в файл; а затем обновить его для включения атрибута parameterOrder(*). Например, в случае, если вы предоставили, вы захотите найти portType, который подключается к интерфейсу и обновить операцию следующим образом:
<portType name="InterfaceName">
<operation name="LoadCustomer" parameterOrder="CustomerId, CustomerName">
<input message="tns:LoadCustomer2Request"/>
<output message="tns:LoadCustomer2Response"/>
</operation>
</portType>
Затем, импортируя обновленную WSDL с помощью WSDL. EXE должен дать вам что-то вроде:
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")]
Я бы предложил открыть КК с просьбой сгенерировать параметрОрдер с помощью WSDL логики Delphi.
Cheers,
Bruneau
PS: (*) Также легко обновить логику генерации WSDL, чтобы сгенерировать параметрОрдер. Прошло много времени с тех пор, как я был в этом коде, но это довольно просто (если я правильно помню:)
.