Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi SoapRequest manipulieren (https://www.delphipraxis.net/192523-soaprequest-manipulieren.html)

BerTa 26. Apr 2017 11:18

SoapRequest manipulieren
 
Hallo,
ich habe ein Problem mit Delphi7 und Soap.
Ich versuche Auftragsdaten aus einem Webshop auszulesen.
Habe die WSDL Datei importiert und kann auch auf den Service zugreifen. Der Login beim Webservice ist ebenfalls möglich.

Nun komme ich zu mein Problem:
Beim Auslesen der Aufträge gebe ich bestimmte Parameter im Request mit. Der erzeugte Request enthält immer alle Parameter was zur Ursache hat, dass ich keine Daten erhalten.

Nun habe ich den Request im Ereignis der HTTPRio Komponente angepasst und erhalte trotzdem keine Daten.
Schaue ich mir den Request im Api-Log des Webshops an, werden hier meine Anpassungen nicht dargestellt.

Es Sieht also so aus, das meine Änderung beim BeforeExecute nicht funktioniert.

Hat jemand eine Idee, woran es scheitert, oder wie ich den Request anderweitig manipulieren kann?

Schöne Grüße

Lemmy 26. Apr 2017 11:26

AW: SoapRequest manipulieren
 
Jup,

schau dir mal die implementierung von TRio.DoBeforeExecute an - da wird aus dem Request ein Stringstream erzeugt, dann in einen String umkopiert und an FOnBeforeExecute übergeben und anschließend wird das Ergebnis verworfen!

Das ist ein heftiger Bug, der leider auch nicht mit den Backports der Änderungen von Delphi 2007 korrigiert wurde.

Hier hilft nur, eine eigenen THttpRio Ableitung, in der habe ich dann zudem anstelle der alten Signatur gleich die Signatur von aktuellen Delphiversionen übernommen (sprich arbeite gleich mit dem Stream weiter und kopiere das Zeugs nicht erst noch in einen String um):

Delphi-Quellcode:
  TBeforeExecuteStreamEvent = procedure(const MethodName: string; SOAPRequest: TStream) of object;

  THTTPRIO_Stream=class(THTTPRIO)
  private
    FOnBeforeExecuteStream: TBeforeExecuteStreamEvent;
    procedure SetOnBeforeExecuteStream(const Value: TBeforeExecuteStreamEvent);
  protected
    procedure DoBeforeExecute(const MethodName: string; Request: TStream); override;
    procedure DoAfterExecute(const MethodName: string; Response: TStream); override;
  public
    property OnBeforeExecuteStream: TBeforeExecuteStreamEvent read FOnBeforeExecuteStream write SetOnBeforeExecuteStream;
    procedure AfterConstruction; override;

  end;
Du musst dann halt beim Aufruf deines Service eine eigene Instanz der Rio-Klasse übergeben....

BerTa 26. Apr 2017 13:25

AW: SoapRequest manipulieren
 
Hallo Lemmy,
vielen Dank für die schnelle Antwort.
Ich war echt schon am verzweifeln!!!

Habe mich jetzt daran versucht,
bin aber wohl nicht in der Lage.
Muss erlich zugeben, dass ich von bjektorientierter Programmierung nicht die meiste Ahnung habe.

Code:
type
  TBeforeExecuteStreamEvent = procedure(const MethodName: string; SOAPRequest: TStream) of object;
 
  THTTPRIO_Stream=class(THTTPRIO)
  private
    FOnBeforeExecute: TBeforeExecuteStreamEvent;
  protected
    procedure DoBeforeExecute(const MethodName: string; Request: TStream); virtual;
  published
    property OnBeforeExecute: TBeforeExecuteStreamEvent read FOnBeforeExecute write FOnBeforeExecute;
end;

////////////////////////////////////////////////////////////////////////////////
procedure THTTPRIO_Stream.DoBeforeExecute(const MethodName: string; Request: TStream);
var
  StrStrm: TStringStream;
begin
  if Assigned(FOnBeforeExecute) then
  begin
    StrStrm := TStringStream.Create('');
    try
      StrStrm.CopyFrom(Request, 0);
      Request.Position := 0;
      FOnBeforeExecute(MethodName, Request);
    finally
      StrStrm.Free;
    end;
  end;
end;

BerTa 26. Apr 2017 14:15

AW: SoapRequest manipulieren
 
Habe das override vergessen :oops:

Jetzt wird aber die Anfrage von Webservice abgelehnt:

"Fehler Login. Unauthorized Request - Token required"
Code:
<?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:Header
    SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
    xmlns:NS1="urn:plentyclientBrw">
    <NS1:verifyingToken xsi:type="NS1:verifyingToken">
      <UserID xsi:type="xsd:int">XXX_USER_XXX</UserID>
      <Token xsi:type="xsd:string">XXX_Token_XXX</Token>
    </NS1:verifyingToken>
  </SOAP-ENV:Header>
 
  <SOAP-ENV:Body
    SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
    xmlns:NS3="urn:plentywsdl">
   
    <NS2:SearchOrders
      xmlns:NS2="http://www.XXX_Webshop_XXX.de/plenty/api/soap/version200/">
      <oPlentySoapRequest_SearchOrders href="#2" />
    </NS2:SearchOrders>
 
    <NS3:PlentySoapRequest_SearchOrders id="2" xsi:type="NS3:PlentySoapRequest_SearchOrders">
      <OrderID xsi:type="xsd:int">422520</OrderID>
      <GetOrderDeliveryAddress xsi:type="xsd:boolean">false</GetOrderDeliveryAddress>
      <GetOrderCustomerAddress xsi:type="xsd:boolean">false</GetOrderCustomerAddress>
      <GetOrderInfo xsi:type="xsd:boolean">false</GetOrderInfo>
      <GetSalesOrderProperties xsi:type="xsd:boolean">false</GetSalesOrderProperties>
      <GetIncomingPayments xsi:type="xsd:boolean">false</GetIncomingPayments>
      <GetOrderDocumentNumbers xsi:type="xsd:boolean">false</GetOrderDocumentNumbers>
      <GetPaymentInformation xsi:type="xsd:boolean">false</GetPaymentInformation>
    </NS3:PlentySoapRequest_SearchOrders>
  </SOAP-ENV:Body>
</SOAP-ENV:Envelope>
Beim bearbeiten des Streams ist mir ein Fehler unterlaufen. Bin also wieder ein Schritt weiter?!


Die Daten sind in der XML-Datei vorhanden, so wie vorher auch. Habe nur im unteren Teil einige Parameter gelöscht.
Wieso werden denn folgende Attribute erzeugt:
xmlns:NS1="urn:plentyclientBrw"
xmlns:NS3="urn:plentywsdl"

Lemmy 26. Apr 2017 15:12

AW: SoapRequest manipulieren
 
Sorry, mit Soap und Authentifizierung hatte ich bisher nichts zu tun.

Hast Du ggf. ein Testprogramm mit dem Du erfolgreich Anfragen an den Webservice schicken kannst? Dann könntest du (z.B. mit Fiddler) die funktionierenden Nachrichten anschauen und hoffentlich nachvollziehen woran der Fehler liegt....

BerTa 27. Apr 2017 13:30

AW: SoapRequest manipulieren
 
Wenn man mal ne erfolgreiche Anfrage hinbekommen würde.
Wenn ich eine Order Abrufe erhalte ich ein Response und bekomme auch einen Fehler "" ist kein gültiger Gleitkommawert.

Code:
      Service := plentywsdl.GetPlentySoapApiFunctionContainerPort(true,'',HTTPRio1_Stream);

      hdr := verifyingToken.Create;
      hdr.UserID := ConfigRec.UserID;
      hdr.Token := ConfigRec.Token;

      HTTPRio1_Stream.SOAPHeaders.SetOwnsSentHeaders(true);
      HTTPRio1_Stream.SOAPHeaders.Send(hdr);

      Request_SO := PSReq_SearchOrders.Create();
      Request_SO.OrderID := 422731;

      Response_SO := PSRes_SearchOrders.Create();
      Response_SO := Service.SearchOrders(Request_SO);
Response kommt zurück (Hab Ihn mal beim After Execute abgefangen). Aber darauf kommt der besagte Fehler.

Lemmy 27. Apr 2017 13:40

AW: SoapRequest manipulieren
 
Mit TEstprogramm meine ich was fertiges vom Hersteller des Webservice.

Wenn der Response bei dir ankommt, dann schau doch da mal nach wo ggf. deine Wrapperklassen einen Float erwarten, aber ein leeres Feld zurück kommt. Dann kannst Du hier entsprechend eingreifen

BerTa 27. Apr 2017 15:35

AW: SoapRequest manipulieren
 
Kann man den Request auch noch anderweitig übergeben ohne die wsdl-Datei?
Sprich manuell ohne Zugriff auf den Service?
Ich kann mir besser manuell die XML-Datei zusammenstellen, da sonst zu viele Fehler auftreten die korrigiert werden müssen.
Somit kann ich den Response auch selber auslesen.

Keldorn 27. Apr 2017 15:43

AW: SoapRequest manipulieren
 
Hallo,

Das ging recht gut mit soapui. Dort kannst du die wsdl laden und daten testweise eintragen.
Du siehst die beiden request und response-xmls und kannst die mit den von delphi erzeugten gut vergleichen.

Meist liegts an den namesspaces, die delphi mit dazuschreibt. Ich weiß immer noch nicht, wie ich dieses problem richtig umgehe. Ich biegs mir im onbeforeexecute immer grade.

Gruß Frank


Alle Zeitangaben in WEZ +1. Es ist jetzt 11:41 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz