2010-05-31 5 views
0

Je suis en train d'utiliser webservice Java et ont demande de savon:Comment modifier la sérialisation SOAP TXSDateTime dans Delphi 7?

<?xml version="1.0"?> 
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"> 
    <SOAP-ENV:Body xmlns:NS1="http://something/"> 
    <NS1:getRequest id="1"> 
     <sessionId xsi:type="xsd:string"></sessionId> 
     <reportType xsi:type="NS1:reportType">ALL</reportType> 
     <xsd:dateFrom xsi:type="xsd:dateTime">2010-05-30T23:29:43.088+02:00</xsd:dateFrom> 
     <xsd:dateTo xsi:type="xsd:dateTime">2010-05-31T23:29:43.728+02:00</xsd:dateTo> 
    </NS1:getRequest> 
    <parameters href="#1" /> 
    </SOAP-ENV:Body> 
</SOAP-ENV:Envelope> 

Il ne fonctionne pas, parce que webservice ne reconnaît pas les dates en tant que paramètres. Quand je change

 <xsd:dateFrom xsi:type="xsd:dateTime">2010-05-30T23:29:43.088+02:00</xsd:dateFrom> 
     <xsd:dateTo xsi:type="xsd:dateTime">2010-05-31T23:29:43.728+02:00</xsd:dateTo> 

à

 <dateFrom xsi:type="xsd:dateTime">2010-05-30T23:29:43.088+02:00</xsd:dateFrom> 
     <dateTo xsi:type="xsd:dateTime">2010-05-31T23:29:43.728+02:00</xsd:dateTo> 

tout fonctionne bien, mais Delphi (sans modification Delphi code source) ne permet pas de changer XML généré, il n'a que quelques options. Est-il possible de définir des options de conversion, donc TSXDateTime est converti en <dateFrom, pas <xsd:dateFrom tag? Avez-vous rencontré ce problème?

Répondre

0

J'ai trouvé une solution. J'ai hérité de THttpRIO et parce que DoBeforeExecute est virtual, j'ai changé son implémentation (DoBeforeExecute est tiré de Delphi 2007, ce qui permet de changer xml dans OnBeforeExecute). Puis j'ai changé mon généré automatiquement de l'unité WSDL pour utiliser TMyHttpRIO:

unit MyHttpRIO; 

interface 

uses 
    RIO, Classes, SOAPHTTPClient; 

type 
    TMyHttpRIO = class(THttpRIO) 
    procedure DoBeforeExecute(const MethodName: string; Request: TStream); override; 
    private 
    end; 

implementation 

{ TMyHttpRIO } 

procedure TMyHttpRIO.DoBeforeExecute(const MethodName: string; 
    Request: TStream); 
var 
    StrStrm: TStringStream; 
    SavedRequest: WideString; 
    ReqWideStr: WideString; 
begin 
    if Assigned(OnBeforeExecute) then 
    begin 
    { Ideally we would change the signature of this event to take a Stream. 
     The change to stream was necessary for attachment and encoding support. 
     And it makes the event consistent.... However, for the sake of 
     backward compatibility.... } 
    StrStrm := TStringStream.Create(''); 
    try 
     StrStrm.CopyFrom(Request, 0); 
     Request.Position := 0; 
     ReqWideStr := UTF8Decode(StrStrm.DataString); 
     SavedRequest := ReqWideStr; 
     OnBeforeExecute(MethodName, ReqWideStr); 
    finally 
     StrStrm.Free; 
    end; 
    if (Length(SavedRequest) <> Length(ReqWideStr)) or (SavedRequest <> ReqWideStr) then 
    begin 
     // Copy changes made to ReqWideStr in the event back to the Request stream 
     StrStrm := TStringStream.Create(string(ReqWideStr)); 
     try 
     StrStrm.Position := 0; 
     Request.Size := 0; 
     Request.CopyFrom(StrStrm, 0); 
     Request.Position := 0; 
     finally 
     StrStrm.Free; 
     end; 
    end; 
    end; 
end; 

end. 
0

Vous pouvez intercepter le code XML avant désérialisation et modifier le contenu de votre cœur, avec stringreplace. Vous devrez vous connecter à l'un des événements RIO.

Mise à jour: Accrochez-y ici: HTTPRIO1AfterExecute (const NomMéthode: chaîne; SOAPResponse: TStream); Le SOAPResponse est un flux, pas aussi facile à jouer avec une corde, mais il est certainement modifiable. Je peux poster un exemple de code demain après-midi. Editer: OnAfterExecute est présent dans D2007 et plus tard, et vous pouvez l'utiliser dans D2005 en utilisant les sources SOAP D2007. Je ne suis pas sûr de D7! Vous pouvez être SOL. Edit: Sur D7, vous pouvez probablement pirater le code pour fournir votre propre événement OnAfterExecute. c'est-à-dire modifier rio.pas pour inclure le gestionnaire pour vous. En outre, une erreur courante lors de l'utilisation de l'objet flux est l'échec de réinitialisation de la position à 0 lorsque vous avez terminé. Editer: vous pouvez également éditer la requête dans BeforeExecute, mais peut-être pas avec le code Delphi7. En D2010 (que j'ai devant moi maintenant), le SOAPRequest est un flux. En D2007 (avec lequel j'ai beaucoup travaillé, mais en utilisant le code D2007 sur D2005), je crois que c'est une chaîne. Dans mon projet D2005/2007, nous modifions considérablement la requête avec une série d'instructions StringReplace() dans OnBeforeExecute.

+0

Où? Ce n'est pas possible. J'ai écrit à ce sujet en question. THTTPRIO a l'événement OnBeforeExecute et il a même un paramètre avec xml déclaré comme var, mais il n'est toujours pas modifiable. Si vous regardez les sources Delphi, il y a même des notes à ce sujet. – LukLed

+0

Désolé, mais OnAfterExecute se produit après l'exécution de la méthode, il n'y a donc rien à changer. OnAfterExecute contient xml de réponse et je veux changer de demande. – LukLed

+0

@LukLed - désolé à ce sujet. Voir ma dernière addition, pour l'utilisation de BeforeExecute pour éditer le XML. Cela peut ne pas fonctionner dans D7, mais est disponible dans D2005 et plus tard. Vous pourrez peut-être modifier la source pour autoriser la modification de cette chaîne/flux. –