2010-01-04 6 views
5

Quelqu'un pourrait-il nous éclairer sur ce comportement? Il semble que Delphi SOAP définit le résultat de la fonction comme le dernier argument, mais WSDL.exe lit le premier argument à être le résultat de la fonction.Incompatibilité SOAP? Delphi 2010 (Win32) Server et .NET Client permutant 'out-parameter' et 'result'

je la méthode suivante dans un service SOAP Delphi, où la chaîne de résultat est utilisé pour le traitement des erreurs de base:

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

Le WSDL généré ressemble à ceci:

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

Pour une raison , WSDL.exe génère le code C# ci-dessous qui permute les chaînes CustomerName et '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; 
    } 

Répondre

10

Lorsque le SOAP était principalement orienté rpc, des problèmes comme ceux-ci apparaissaient souvent. Il n'y a pas d'ordre spécifique pour déterminer quelle partie est le résultat de la fonction (opération). Le propre importateur de Delphi avait l'habitude de [et probablement encore ??] d'identifier le «résultat» par le nom de la pièce. Et vous pouvez (pouvez?) Spécifier une liste de noms délimitée par des virgules à utiliser. Si aucune des parties ne correspond aux noms, alors s'il y a une sortie, c'est le résultat.

La spécification SOAP. a finalement inclure des ajouts pour résoudre ce problème. L'attribut pertinent dans votre cas est l'attribut 'parameterOrder' (il y a aussi rpc: result pour les données SOAP réelles). Cependant, vous ne voyez pratiquement pas les WSDL qui utilisent l'attribut. Mais, je crois que WSDL.EXE fait attention à cet attribut. Vous pouvez en savoir plus sur parameterOrder ici:

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

Ce que je vous suggère de faire est de sauver le WSDL généré par Delphi dans un fichier; et mettez à jour le dernier pour inclure l'attribut parameterOrder (*). Par exemple, dans le cas que vous avez fourni, vous voulez trouver le portType qui correspond à l'interface et mettre à jour l'opération comme suit:

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

Ensuite, l'importation que WSDL mis à jour avec wsdl.exe devrait vous donner quelque chose le long des lignes 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])); 
    } 

Vous devriez également voir l'attribut suivant la méthode ci-dessus pour confirmer que le « retour » est le résultat en effet:

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

Je voudrais SUG gest ouvrant un QC demandant que le parameterOrder soit généré par la logique WSDL de Delphi.

Cheers,

Bruneau

PS: (*) Il est également facile de mettre à jour la logique de génération WSDL pour émettre parameterOrder. Cela fait longtemps que je suis dans ce code mais c'est assez simple (si je me souviens bien :)