2010-01-04 9 views
5

¿Podría alguien arrojar algo de luz sobre este comportamiento? Parece que Delphi SOAP establece el resultado de la función como último argumento, pero WSDL.exe lee el primer argumento como el resultado de la función.¿Incoherencia de SOAP? Delphi 2010 (Win32) Servidor y cliente .NET intercambiando 'out-parameter' y 'result'

tengo el método siguiente en un servicio SOAP Delphi, donde se utiliza la cadena de resultado para el tratamiento de errores básicos:

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

El WSDL generado es el siguiente:

<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> 

Por alguna razón WSDL.exe genera el siguiente código C# que intercambia las cadenas CustomerName y '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 = [email protected]; 
     return retVal.CustomerName; 
    } 

Respuesta

10

Cuando SOAP estaba predominantemente orientado a rpc, los problemas como estos surgían a menudo. No hay un orden específico para determinar qué parte es el resultado de la función (operación). El propio importador de Delphi solía [y probablemente todavía lo hace ??] identificar el 'resultado' por el nombre de la parte. Y podría (¿puede?) Especificar una lista de nombres delimitados por comas para usar. Si ninguna de las partes coincide con los nombres, entonces si hay una sola, es el resultado.

La especificación SOAP. finalmente incluyó adiciones para resolver este problema. El más relevante en su caso es el atributo 'parameterOrder' (también hay rpc: resultado para los datos reales de SOAP). Sin embargo, apenas ves los WSDL que usan el atributo. Pero, creo que WSDL.EXE presta atención a ese atributo. Puede encontrar más información acerca de parameterOrder aquí:

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

Lo que sugeriría que hacer es salvar el WSDL generado por Delphi en un archivo; y actualice el último para incluir el atributo parameterOrder (*). Por ejemplo, en el caso que nos ha facilitado, tendrá que encontrar la portType que se asigna a la interfaz y actualizar el funcionamiento de la siguiente manera:

<portType name="InterfaceName"> 
    <operation name="LoadCustomer" parameterOrder="CustomerId, CustomerName"> 
     <input message="tns:LoadCustomer2Request"/> 
     <output message="tns:LoadCustomer2Response"/> 
    </operation> 
    </portType> 

A continuación, la importación de WSDL que actualizada con Wsdl.exe debería darle algo a lo largo de las líneas de:

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

también debe ver el siguiente atributo sobre el método para confirmar que 'retorno' es el lugar efectivamente:

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

lo haría sug abriendo un control de calidad que solicita que el parameterOrder sea generado por la lógica WSDL de Delphi.

Saludos,

Bruneau

PS: (*) También es fácil de actualizar la lógica de generación de WSDL para emitir parameterOrder. Ha pasado mucho tiempo desde que estuve en ese código, pero es bastante directo (si no recuerdo mal :)