Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi HTTPRIO SOAP Header/Request ändern D2006 (https://www.delphipraxis.net/206447-httprio-soap-header-request-aendern-d2006.html)

DennisR 22. Dez 2020 16:55

Delphi-Version: 5

HTTPRIO SOAP Header/Request ändern D2006
 
Hallo zusammen.
Bin gerade dabei einen lokalen WebService anzusprechen und via XML die Daten hin und her zu schubsen.

Verbindung usw. klappt alles, zumindest wenn ich den XML-Text per Hand schreibe und als WideString übergebe.
Das Problem habe ich, wenn ich den durch Delphi erstellen Quellcode zur WSDL benutze:
Der Text des per Hand geschriebenen und automatisch erstellten weicht eigentlich nur in den ersten paar Zeilen ab, alles danach ist fast identisch.

Über das OnBeforeExecute wollte ich nun den Request stumpf per StringReplace abändern.
Delphi-Quellcode:
procedure Tdmt.htprMainBeforeExecute(const MethodName: string;
  var SOAPRequest: WideString);
var
  test: WideString;
begin
  test := SOAPRequest;
  test := StringReplace(test,WideString('<s:Header xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"> + #13#10'),'');
  test := StringReplace(test,WideString('<To s:mustUnderstand="1" xmlns="http://schemas.microsoft.com/ws/2005/05/addressing/none">http://localhost:1200/38f9edad-b272-4649-917e-1180b4c5207e</To>' + #13#10),'');
  test := StringReplace(test,WideString('<Action s:mustUnderstand="1" xmlns="http://schemas.microsoft.com/ws/2005/05/addressing/none">http://tempuri.org/IPOS/Sign</Action>' + #13#10),'');
  test := StringReplace(test,WideString('</s:Header>' + #13#10),'');
  test := StringReplace(test,WideString('<data'),'<tem:data');
  test := StringReplace(test,WideString('</data'),'</tem:data');
  SOAPRequest := test;
end;
Wenn ich mir während des Debuggens den Text anschaue, passt er auch. Wenn ich in die Konsole meines WebService schaue, kommt es aber so an, als ob ich überhaupt keine Änderungen gemacht hätte.

Könnte mir hier evtl. jemand auf die Sprünge helfen?

himitsu 22. Dez 2020 17:04

AW: HTTPRIO SOAP Header/Request ändern D2006
 
Ich glaub du hast falsch geguckt.
* beim ersten StringReplace kann es niemals funktionieren, da du das #13#10 als "Text" im String hast


Und bist du dir sicher, dass es auch im Service genau so aussieht?
* anderer Zeilenumbruch, wie z.B. #10
* andere Formatierung
* ...

Den WebService debuggen
und/oder die Funktion/Ergebnisse in ein Log schreiben.


Und wie wäre es, wenn das XML auch als XML behandelst, also mit einer XML-Komponente, anstatt darin manuell mit String-Funktionen rumzupfuschen?

DennisR 22. Dez 2020 18:32

AW: HTTPRIO SOAP Header/Request ändern D2006
 
Mahlzeit.

Ich habe erwähnt, dass ich die von Delphi selbst erstellten Klassen (TRemotable) aus der WSDL benutze. Ich greife hier nur ein, weil der Text in falscher Form übermittelt wird.
Der Service hat 3 Funktionen, wovon zwei funktionieren, nur bei dieser scheint Delphi irgendeinen Mist zu senden.

Es ist ein lokaler WebService, aber von einem Drittanbieter (Fiskaltrust), daher ist Debuggen nicht drin. In der Konsole wird mir angezeigt, was beim WebService ankommt, und das ist der Text, vor meinen Änderungen im OnBeforeExecute.

Des Weiteren ist mir aufgefallen, dass ich die ersten 4 Zeilen, welche ich ersetzen will, überhaupt nicht in SOAPMessage finde. Das wird anscheinend erst beim Versenden hinzugedichtet. Das 5te und 6te StringReplace findet aber statt, wonach ich mich ganze Zeit dran orientiert hab.

Habt bitte Nachsehen, ich bin Neuling was WebServices angeht. Zu der kack-alten Delphi Version findet man leider auch recht wenig zu dem Problem.

DennisR 23. Dez 2020 10:10

AW: HTTPRIO SOAP Header/Request ändern D2006
 
Um es nochmal zu verdeutlichen:

Das hier wird durch Delphi verschickt

Code:
<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">
  <s:Header xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
    <To s:mustUnderstand="1" xmlns="http://schemas.microsoft.com/ws/2005/05/addressing/none">http://localhost:1200/38f9edad-b272-4649-917e-1180b4c5207e</To>
    <Action s:mustUnderstand="1" xmlns="http://schemas.microsoft.com/ws/2005/05/addressing/none">http://tempuri.org/IPOS/Sign</Action>
  </s:Header>
  <SOAP-ENV:Body>
    <Sign xmlns="http://tempuri.org/">
      <data xmlns="http://schemas.datacontract.org/2004/07/fiskaltrust.ifPOS.v0">
        <ftCashBoxID>d797b413-7cb6-43b3-8ff0-3594f60ae3cd</ftCashBoxID>
        <ftQueueID></ftQueueID>
        <ftPosSystemId></ftPosSystemId>
        <cbTerminalID>1</cbTerminalID>
        <cbReceiptReference>INIT</cbReceiptReference>
        <cbReceiptMoment>2020-12-21T11:23:00.362Z</cbReceiptMoment>
        <cbChargeItems></cbChargeItems>
        <cbPayItems></cbPayItems>
        <ftReceiptCase>4919338172267102211</ftReceiptCase>
        <ftReceiptCaseData></ftReceiptCaseData>
        <cbReceiptAmount xsi:nil="true" xmlns=""></cbReceiptAmount>
        <cbUser>Admin</cbUser>
        <cbArea></cbArea>
        <cbCustomer></cbCustomer>
        <cbSettlement></cbSettlement>
        <cbPreviousReceiptReference></cbPreviousReceiptReference>
      </data>
    </Sign>
  </SOAP-ENV:Body>
</SOAP-ENV:Envelope>
und es klappt nicht.

So schicke ich es per SoapUI:
Code:
<SOAP-ENV:Envelope xmlns:tem="http://tempuri.org/" 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">
    <SOAP-ENV:Body>
        <Sign xmlns="http://tempuri.org/">
        <tem:data xmlns="http://schemas.datacontract.org/2004/07/fiskaltrust.ifPOS.v0">
            <ftCashBoxID>d797b413-7cb6-43b3-8ff0-3594f60ae3cd</ftCashBoxID>
            <ftQueueID></ftQueueID>
            <ftPosSystemId></ftPosSystemId>
            <cbTerminalID>1</cbTerminalID>
            <cbReceiptReference>INIT</cbReceiptReference>
            <cbReceiptMoment>2020-10-27T11:19:43.962Z</cbReceiptMoment>
            <cbChargeItems></cbChargeItems>
            <cbPayItems></cbPayItems>
            <ftReceiptCase>4919338172267102211</ftReceiptCase>
            <ftReceiptCaseData></ftReceiptCaseData>
            <cbReceiptAmount xmlns="" xsi:nil="true"/>
            <cbUser>Admin</cbUser>
            <cbArea></cbArea>
            <cbCustomer></cbCustomer>
            <cbSettlement></cbSettlement>
            <cbPreviousReceiptReference></cbPreviousReceiptReference>
        </tem:data>
        </Sign>
    </SOAP-ENV:Body>
</SOAP-ENV:Envelope>
und es klappt. Ich müsste also nur den Header rausschmeißen (OnBeforeExecute - hat aber keine Auswirkung, Text wird unverändert geschickt), sowie das data durch tem:data ersetzen.

Aufgerufen wird das ganze dann so:
Delphi-Quellcode:
      RecMoment.AsUtcDateTime := Now;
      Receipt.ftCashBoxID := 'd797b413-7cb6-43b3-8ff0-3594f60ae3cd';
      Receipt.cbTerminalID := '1';
      Receipt.cbReceiptReference := 'INIT';
      Receipt.cbReceiptMoment := RecMoment;

      aXmlDecimal.DecimalString := '0';

      aChargeItem.Quantity := aXmlDecimal;
      aChargeItem.Amount := aXmlDecimal;
      aChargeItem.VATRate := aXmlDecimal;
      aChargeItem.ftChargeItemCase := 0;

      apayitem.Quantity := aXmlDecimal;
      apayitem.Amount := aXmlDecimal;
      apayitem.ftPayItemCase := 0;

      SetLength(arChItems,1);
      arChItems[0] := aChargeItem;

      Receipt.cbChargeItems := arChItems;

      SetLength(arPayItems,1);
      arPayItems[0] := apayitem;

      Receipt.cbPayItems := arPayItems;

      Receipt.ftReceiptCase := 4919338172267102211;
      Receipt.cbUser := 'Admin';

      try
        Response := test.Sign(Receipt);
      finally
        erg := Response.ftStateData;
      end;
Die einzelnen Klassen sehen in der Regel so aus:
Delphi-Quellcode:
ReceiptRequest = class(TRemotable)
  private
    FftCashBoxID: WideString;
    ....
  public
    destructor Destroy; override;
  published
    property ftCashBoxID: WideString read FftCashBoxID write FftCashBoxID;
    ....
  end;
Delphi-Quellcode:
initialization
  InvRegistry.RegisterInterface(TypeInfo(IPOS), 'http://tempuri.org/', 'utf-8');
  InvRegistry.RegisterAllSOAPActions(TypeInfo(IPOS), '|http://tempuri.org/IPOS/Sign|http://tempuri.org/IPOS/Journal|http://tempuri.org/IPOS/Echo|http://tempuri.org/IPOS/v1/Sign|http://tempuri.org/IPOS/v1/Journal|http://tempuri.org/IPOS/v1/Echo');
  InvRegistry.RegisterInvokeOptions(TypeInfo(IPOS), ioDocument);
  InvRegistry.RegisterExternalParamName(TypeInfo(IPOS), 'Journal', 'to_', 'to');
  InvRegistry.RegisterExternalParamName(TypeInfo(IPOS), 'Echo', 'message_', 'message');
  InvRegistry.RegisterExternalParamName(TypeInfo(IPOS), 'v1_x002F_Echo', 'message_', 'message');
  RemClassRegistry.RegisterXSClass(EchoRequest, 'http://schemas.datacontract.org/2004/07/fiskaltrust.ifPOS.v1', 'EchoRequest');
  RemClassRegistry.RegisterExternalPropName(TypeInfo(EchoRequest), 'Message_', 'Message');
  RemClassRegistry.RegisterXSClass(EchoResponse, 'http://schemas.datacontract.org/2004/07/fiskaltrust.ifPOS.v1', 'EchoResponse');
  RemClassRegistry.RegisterExternalPropName(TypeInfo(EchoResponse), 'Message_', 'Message');
  RemClassRegistry.RegisterXSClass(JournalRequest, 'http://schemas.datacontract.org/2004/07/fiskaltrust.ifPOS.v1', 'JournalRequest');
  RemClassRegistry.RegisterExternalPropName(TypeInfo(JournalRequest), 'To_', 'To');
  RemClassRegistry.RegisterXSInfo(TypeInfo(StreamBody), 'http://schemas.microsoft.com/Message', 'StreamBody');
  RemClassRegistry.RegisterXSInfo(TypeInfo(ArrayOfChargeItem), 'http://schemas.datacontract.org/2004/07/fiskaltrust.ifPOS.v0', 'ArrayOfChargeItem');
  RemClassRegistry.RegisterXSInfo(TypeInfo(ArrayOfPayItem), 'http://schemas.datacontract.org/2004/07/fiskaltrust.ifPOS.v0', 'ArrayOfPayItem');
  RemClassRegistry.RegisterXSClass(ReceiptRequest, 'http://schemas.datacontract.org/2004/07/fiskaltrust.ifPOS.v0', 'ReceiptRequest');
  RemClassRegistry.RegisterXSClass(ChargeItem, 'http://schemas.datacontract.org/2004/07/fiskaltrust.ifPOS.v0', 'ChargeItem');
  RemClassRegistry.RegisterExternalPropName(TypeInfo(ChargeItem), 'Unit_', 'Unit');
  RemClassRegistry.RegisterXSClass(PayItem, 'http://schemas.datacontract.org/2004/07/fiskaltrust.ifPOS.v0', 'PayItem');
  RemClassRegistry.RegisterXSInfo(TypeInfo(ArrayOfstring), 'http://schemas.microsoft.com/2003/10/Serialization/Arrays', 'ArrayOfstring');
  RemClassRegistry.RegisterXSInfo(TypeInfo(ArrayOfSignaturItem), 'http://schemas.datacontract.org/2004/07/fiskaltrust.ifPOS.v0', 'ArrayOfSignaturItem');
  RemClassRegistry.RegisterXSClass(ReceiptResponse, 'http://schemas.datacontract.org/2004/07/fiskaltrust.ifPOS.v0', 'ReceiptResponse');
  RemClassRegistry.RegisterXSClass(SignaturItem, 'http://schemas.datacontract.org/2004/07/fiskaltrust.ifPOS.v0', 'SignaturItem');
  RemClassRegistry.RegisterXSInfo(TypeInfo(ArrayOfChargeItem2), 'http://schemas.datacontract.org/2004/07/fiskaltrust.ifPOS.v1', 'ArrayOfChargeItem2', 'ArrayOfChargeItem');
  RemClassRegistry.RegisterXSInfo(TypeInfo(ArrayOfPayItem2), 'http://schemas.datacontract.org/2004/07/fiskaltrust.ifPOS.v1', 'ArrayOfPayItem2', 'ArrayOfPayItem');
  RemClassRegistry.RegisterXSClass(ReceiptRequest2, 'http://schemas.datacontract.org/2004/07/fiskaltrust.ifPOS.v1', 'ReceiptRequest2', 'ReceiptRequest');
  RemClassRegistry.RegisterXSClass(ChargeItem2, 'http://schemas.datacontract.org/2004/07/fiskaltrust.ifPOS.v1', 'ChargeItem2', 'ChargeItem');
  RemClassRegistry.RegisterExternalPropName(TypeInfo(ChargeItem2), 'Unit_', 'Unit');
  RemClassRegistry.RegisterXSClass(PayItem2, 'http://schemas.datacontract.org/2004/07/fiskaltrust.ifPOS.v1', 'PayItem2', 'PayItem');
  RemClassRegistry.RegisterXSInfo(TypeInfo(ArrayOfSignaturItem2), 'http://schemas.datacontract.org/2004/07/fiskaltrust.ifPOS.v1', 'ArrayOfSignaturItem2', 'ArrayOfSignaturItem');
  RemClassRegistry.RegisterXSClass(ReceiptResponse2, 'http://schemas.datacontract.org/2004/07/fiskaltrust.ifPOS.v1', 'ReceiptResponse2', 'ReceiptResponse');
  RemClassRegistry.RegisterXSClass(SignaturItem2, 'http://schemas.datacontract.org/2004/07/fiskaltrust.ifPOS.v1', 'SignaturItem2', 'SignaturItem');

DennisR 29. Dez 2020 13:05

AW: HTTPRIO SOAP Header/Request ändern D2006
 
Hallo.

Da hatte Delphi2006 anscheinend einen Fehler in der WSDLImp.exe. Nach Download des Patches ( http://cc.embarcadero.com/Item/24535 ) und Neuerstellung der WSDL.pas funktioniert die Kommunikation mit dem Webservice nun einwandfrei.


Alle Zeitangaben in WEZ +1. Es ist jetzt 13:48 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