Results 1 to 15 of 15

Thread: Alternatief voor request sturen naar webservice

  1. #1
    John Kuiper
    Join Date
    Apr 2007
    Location
    Almere
    Posts
    8,747

    Alternatief voor request sturen naar webservice

    Is er een andere manier buiten THTTPRIO in de imported WSDL unit een request te sturen naar een webservice. Mijn probleem is dat de import van de WSDL niet de volledige objecten aanmaakt. Ik krijg namelijk de volgende melding na de import:
    Delphi Code:
    1. // ************************************************************************ //
    2.   // The following types, referred to in the WSDL document are not being represented
    3.   // in this file. They are either aliases[@] of other types represented or were referred
    4.   // to but never[!] declared in the document. The types from the latter category
    5.   // typically map to predefined/known XML or Embarcadero types; however, they could also
    6.   // indicate incorrect WSDL documents that failed to declare or import a schema type.
    7.   // ************************************************************************ //
    8.   // !:TransportUnitType - "urn:fec:florecom:xml:data:draft:ReusableAggregateBusinessInformationEntity:3"[!U][Gbl]
    9.   // !:StatusType      - "urn:fec:florecom:xml:data:draft:ReusableAggregateBusinessInformationEntity:3"[!U][Gbl]
    10.   // !:LegType         - "urn:fec:florecom:xml:data:draft:ReusableAggregateBusinessInformationEntity:3"[!U][Gbl]
    11.   // !:TradingTermsType - "urn:fec:florecom:xml:data:draft:ReusableAggregateBusinessInformationEntity:3"[!U][Gbl]
    12.   // !:PriceType       - "urn:fec:florecom:xml:data:draft:ReusableAggregateBusinessInformationEntity:3"[!U][Gbl]
    13.   // !:PackageType     - "urn:fec:florecom:xml:data:draft:ReusableAggregateBusinessInformationEntity:3"[!U][Gbl]
    14.   // !:TransportEquipmentType - "urn:fec:florecom:xml:data:draft:ReusableAggregateBusinessInformationEntity:3"[!U][Gbl]
    15.   // !:TradeLineItemType - "urn:fec:florecom:xml:data:draft:ReusableAggregateBusinessInformationEntity:3"[!U][Gbl]
    16.   // !:TemperatureType - "urn:fec:florecom:xml:data:draft:ReusableAggregateBusinessInformationEntity:3"[!U][Gbl]
    17.   // !:RegulatoryProcedureType - "urn:fec:florecom:xml:data:draft:ReusableAggregateBusinessInformationEntity:3"[!U][Gbl]
    18.   // !:ShippingMarksType - "urn:fec:florecom:xml:data:draft:ReusableAggregateBusinessInformationEntity:3"[!U][Gbl]
    19.   // !:LocationType    - "urn:fec:florecom:xml:data:draft:ReusableAggregateBusinessInformationEntity:3"[!U][Gbl]
    20.   // !:NotifyPartyType - "urn:fec:florecom:xml:data:draft:ReusableAggregateBusinessInformationEntity:3"[!U][Gbl]
    21.   // !:PeriodType      - "urn:fec:florecom:xml:data:draft:ReusableAggregateBusinessInformationEntity:3"[!U][Gbl]
    22.   // !:TradePriceType  - "urn:fec:florecom:xml:data:draft:ReusableAggregateBusinessInformationEntity:3"[!U][Gbl]
    23.   // !:ProductType     - "urn:fec:florecom:xml:data:draft:ReusableAggregateBusinessInformationEntity:3"[!U][Gbl]
    24. .............
    Delphi is great. Lazarus is more powerfull

  2. #2
    Dat kan zeker, het is uiteindelijk gewoon tekst wat je stuurt tenslotte. Maar je moet je afvragen of je er heel blij van wordt, je moet dan de hele XML zelf gaan opbouwen. Dan zou ik eerder afwijken naar een andere omgeving die je WSDL wel snapt, dat lijkt me dan een stuk simpeler.
    Marcel

  3. #3
    John Kuiper
    Join Date
    Apr 2007
    Location
    Almere
    Posts
    8,747
    Door de tijdsdruk wil ik het best handmatig aanmaken en doorsturen. Kan dat met dezelfde THTTPRio?
    Delphi is great. Lazarus is more powerfull

  4. #4
    Nee, dat doe je dan gewoon door de XML te posten, dus Indy lijkt me dan het handigst. Kijk naar dit Hello World voorbeeld: http://toolkit.apada.nl/webservices/...orld.asmx?WSDL

    De Hello method is simpel:

    C# Code:
    1. [WebMethod]
    2.     public string Hello(string name)
    3.     {
    4.       return $"Hello {name}";
    5.     }

    De request voor deze method is:
    HTML Code:
    1. POST [url]http://toolkit.apada.nl/webservices/helloworld.asmx[/url] HTTP/1.1
    2. Accept-Encoding: gzip,deflate
    3. Content-Type: text/xml;charset=UTF-8
    4. SOAPAction: "http://toolkit.apada.nl/Hello"
    5. Content-Length: 304
    6. Host: toolkit.apada.nl
    7. Connection: Keep-Alive
    8. User-Agent: Apache-HttpClient/4.1.1 (java 1.5)
    9.  
    10. <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:tool="http://toolkit.apada.nl/">
    11.    <soapenv:Header/>
    12.    <soapenv:Body>
    13.       <tool:Hello>
    14.          <!--Optional:-->
    15.          <tool:name>Marcel</tool:name>
    16.       </tool:Hello>
    17.    </soapenv:Body>
    18. </soapenv:Envelope>

    En de response:

    HTML Code:
    1. HTTP/1.1 200 OK
    2. Cache-Control: private, max-age=0
    3. Content-Type: text/xml; charset=utf-8
    4. Server: Microsoft-IIS/7.5
    5. X-AspNet-Version: 4.0.30319
    6. X-Powered-By: ASP.NET
    7. Date: Thu, 22 Dec 2016 09:09:33 GMT
    8. Content-Length: 349
    9.  
    10. <?xml version="1.0" encoding="utf-8"?>
    11. <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    12.   <soap:Body>
    13.     <HelloResponse xmlns="http://toolkit.apada.nl/">
    14.       <HelloResult>Hello Marcel</HelloResult>
    15.     </HelloResponse>
    16.   </soap:Body>
    17. </soap:Envelope>

    Je ziet dat er voor een simpele Hello World al een flink stukje XML bij komt kijken. Maar het is zeker mogelijk om dat zelf samen te stellen. Voor bovenstaande voorbeelden heb ik SoapUI en Fiddler gebruikt. Je stappenplan:


    • Installeer SoapUI
    • Installeer Fiddler
    • Lees de WSDL in SoapUI in
    • Vul de variabelen in de methods in
    • Voer de request uit
    • Bekijk de XML (of de raw output) in Fiddler


    Je weet nu wat er verzonden moet worden en wat er terug komt. Dat moet je dus gaan samenstellen en parsen. Dat gaat best complex worden vrees ik, dus veel succes
    Marcel

  5. #5
    John Kuiper
    Join Date
    Apr 2007
    Location
    Almere
    Posts
    8,747
    De structuur van de request en response heb ik al (dankzij SoapUI en de website van de partij).
    Mag ik aannemen dat TidHTTP.post moet gebruiken?
    Ik heb deze gegevens:
    function GetGovernmentExporterPorts(UseWSDL: Boolean; Addr: string; HTTPRIO: THTTPRIO): GovernmentExporterPorts;
    const
    defWSDL = 'https://acclongexport.bkd.eu/ws/krce_com.php?wsdl';
    defURL = 'https://acclongexport.bkd.eu/ws/krce_com.php';
    defSvc = 'GovernmentExporter';
    defPrt = 'ExportPort';
    end;
    Dan zal het adres de variable deURL moeten zijn. Maar hoe zit het dan met de variable defSvc en defPrt? Moeten die ook ergens worden opgegeven? Ik zie dat SoapUI alleen de URL gebruikt.
    Delphi is great. Lazarus is more powerfull

  6. #6
    Wat is de ruwe header van de post in SoapUI?
    Marcel

  7. #7
    John Kuiper
    Join Date
    Apr 2007
    Location
    Almere
    Posts
    8,747
    Als ik het goed heb gedaan is dit de raw data
    Delphi Code:
    1. POST [url]https://acclongexport.bkd.eu/ws/krce_com.php[/url] HTTP/1.1
    2. Accept-Encoding: gzip,deflate
    3. Content-Type: text/xml;charset=UTF-8
    4. SOAPAction: "http://webservices.client.florecom.org/Government/exporter/PutCertificate_315"
    5.  
    6. <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:urn="urn:fec:florecom:xml:data:draft:ClientStandardMessage:1" xmlns:urn1="urn:un:unece:uncefact:data:standard:ReusableAggregateBusinessInformationEntity:3" xmlns:urn2="urn:fec:florecom:xml:data:draft:ReusableAggregateBusinessInformationEntity:3">
    7.    <soapenv:Header/>
    8.    <soapenv:Body>
    9.       <urn:PutCertificateRequest>
    10.          <urn:Header>
    11.             <!--Optional:-->
    12.             <urn:UserName languageCode="?">?</urn:UserName>
    13.             <!--Optional:-->
    14.             <urn:Password languageCode="?">?</urn:Password>
    15.             <urn:MessageID schemeID="?" schemeName="?" schemeAgencyID="?" schemeAgencyName="?" schemeVersionID="?" schemeDataURI="?" schemeURI="?">?</urn:MessageID>
    16.             <urn:MessageDateTime>?</urn:MessageDateTime>
    17.             <urn:MessageSerial>?</urn:MessageSerial>
    Dit is de XML
    Delphi Code:
    1. <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:urn="urn:fec:florecom:xml:data:draft:ClientStandardMessage:1" xmlns:urn1="urn:un:unece:uncefact:data:standard:ReusableAggregateBusinessInformationEntity:3" xmlns:urn2="urn:fec:florecom:xml:data:draft:ReusableAggregateBusinessInformationEntity:3">
    2.    <soapenv:Header/>
    3.    <soapenv:Body>
    4.       <urn:PutCertificateRequest>
    5.          <urn:Header>
    6.             <!--Optional:-->
    7.             <urn:UserName languageCode="?">?</urn:UserName>
    8.             <!--Optional:-->
    9.             <urn:Password languageCode="?">?</urn:Password>
    10.             <urn:MessageID schemeID="?" schemeName="?" schemeAgencyID="?" schemeAgencyName="?" schemeVersionID="?" schemeDataURI="?" schemeURI="?">?</urn:MessageID>
    11.             <urn:MessageDateTime>?</urn:MessageDateTime>
    12.             <urn:MessageSerial>?</urn:MessageSerial>
    13.             <!--Zero or more repetitions:-->
    Delphi is great. Lazarus is more powerfull

  8. #8
    OK, nou ga je dus de variabelen vullen (de vraagtekens) en vervolgens POST je die string op de URL. Dat kun je eerst in SoapUI doen, vervolgens ga je dat exact zelf nabouwen tot je hetzelfde resultaat krijgt. Vervolgens ga je het resultaat parsen.
    Marcel

  9. #9
    John Kuiper
    Join Date
    Apr 2007
    Location
    Almere
    Posts
    8,747
    Ik ga mijn best doen (heb weinig keus).
    Sowieso maak ik altijd een testscherm aan, om te kijken wat de communicatie terug is van de webservice.
    Delphi is great. Lazarus is more powerfull

  10. #10
    John Kuiper
    Join Date
    Apr 2007
    Location
    Almere
    Posts
    8,747
    Ik kom er niet uit. Inmiddels heb ik een stukje xml, die gelijk is aan de xml, die gestuurd wordt via THTTPRio. Ik heb tidHTTP gedclareerd en de volgende code ingevoerd:
    Delphi Code:
    1. function TBericht50.Verwerk(aLines : TStrings): string;
    2. var ReqPost            : TidHttp;
    3.     MyStream           : TmemoryStream;
    4. begin
    5.   result := '';
    6.   ReqPost               := TidHttp.Create(nil);
    7.   MyStream           := TmemoryStream.Create;
    8.   try
    9.     ...............
    10.     Request.GetStream.SaveToStream(MyStream);
    11.     ReqPost.Request.URL  := 'https://acclongexport.bkd.eu/ws/krce_com.php';
    12.     ReqPost.Request.Host := 'acclongexport.bkd.eu';
    13.     ReqPost.Request.Source := Mystream;
    14.     ReqPost.Connect;
    15.   finally
    16.     ReqPost.Free;
    17.   end;
    18. end;
    Ondanks dat ik de host heb ingevoerd komt delphi met de melding terug:
    Project ketenregister.exe raised exception class EIdHostRequired with message 'A Host is required'.
    Ik vul volgens mij de verkeerde gegevens in.
    Delphi is great. Lazarus is more powerfull

  11. #11
    Waarom een ReqPost.Connect en niet een .Get() of .Post().

    De connect maakt verbinding en dan moet de Host in IOHandler gezet zijn (volg de code maar eens). Als eerste staat er gelijk dit:
    Delphi Code:
    1. procedure TIdTCPClientCustom.Connect;
    2. begin
    3.   if Connected then begin
    4.     raise EIdAlreadyConnected.Create(RSAlreadyConnected);
    5.   end;
    6.  
    7.   if Host = '' then begin
    8.     raise EIdHostRequired.Create('A Host is required'); {do not localize}
    9.   end;
    10.   if Port = 0 then begin
    11.     raise EIdPortRequired.Create('A Port is required'); {do not localize}
    12.   end;
    13.  
    14.   if IOHandler = nil then begin
    15.     IOHandler := MakeImplicitClientHandler;
    16.  
    17.                                                                                    
    18.     IOHandler.OnStatus := OnStatus;
    19.  
    20.     ManagedIOHandler := True;
    21.   end;
    Probleem is alleen dat die Host pas "gezet" kan worden na de MakeImplicitClientHandler. Dus je zou de "locale" Host van TIdHTTP.Host zelf moeten zetten maar die is niet public gemaakt voor die descendant.

    Daarom "haat" ik Indy... dat is allemaal zo lekker doorzichtig

    Maar met een TIdHTTP.Get() of TIdHTTP.Post() gaat het wel goed.

  12. #12
    Stijn Sanders develyoy's Avatar
    Join Date
    Jun 2008
    Location
    GentBrugge, Belgi?½
    Posts
    1,046
    Voor zo'n dingen kies ikzelf de laatste tijd meer en meer gewoon het XMLHTTP object uit MSXML2_TLB.pas die je krijgt als je de "Microsoft XML" ActiveX library importeert... Het zit allemaal anders ineen dan Indy, maar een stuk doorzichtiger. Ik zou even moeten zoeken voor een stukje voorbeeld data, maar behalve "CoXMLHTTP.Create" is het gewoon ".open('POST',url)" en dan ".send()" waar je rechtstreeks de XML in kan zetten (heel misschien nog een setRequestHeader('Content-Type','text/xml') daartussen maar soms is die niet nodig).

  13. #13
    John Kuiper
    Join Date
    Apr 2007
    Location
    Almere
    Posts
    8,747
    Ik ben ook geen fan van Indy. Krijg nu het gezeur de de ssl library niet gevonden kan worden. Maar dat is een probleem wat opgelost kan worden.

    @develyoy
    Normaal gebruik ik httprio, die naast mijn gevonden headers van de WSDL het bericht kan versturen via de Windows standaard (als dat zo is, tenminste). die heeft alle protocollen in zich. Maar dat nu net niet alles headers gevonden zijn en daardoor een incompleted import heb is heel irritant. Maar ik hou het wel als zijdeurtje in mijn hoofd
    Delphi is great. Lazarus is more powerfull

  14. #14
    John Kuiper
    Join Date
    Apr 2007
    Location
    Almere
    Posts
    8,747
    Oke. SSL aangemaakt post verzonden en levert een internal error op.
    Project ketenregister.exe raised exception class EIdHTTPProtocolException with message 'HTTP/1.1 500 Internal Server Error'.
    Op het internet gezocht voor een goede oplossing van debuggen. Deze aangemaakt. De logfile geeft o.a. de volgende melding terug:
    17-01-03 12:21:14 << HTTP/1.1 500 Internal Service Error<EOL>Date: Tue, 03 Jan 2017 11:21:10 GMT<EOL>Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0<EOL>Pragma: no-cache<EOL>Set-Cookie: PHPSESSID=nmqa7ctqv9rj1orje0rtf0prp5; path=/<EOL>Expires: Thu, 19 Nov 1981 08:52:00 GMT<EOL>Content-Length: 354<EOL>Content-Type: text/xml; charset=utf-8<EOL>X-FRAME-OPTIONS: SAMEORIGIN<EOL>Set-Cookie: BNES_PHPSESSID=t2FVnW6zgAytX+R7YuyL0BFnlURKv/QLU90yine+HjiD1zh2SoqIS6W27HbMCnlM2p71GRqpTcMiNjPd Og7sKg==; path=/<EOL><EOL><?xml version="1.0" encoding="UTF-8"?><LF><SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"><SOAP-ENV:Body><SOAP-ENV:Fault><faultcode>soap-Client</faultcode><faultstring>Er is geen geldige datum opgegeven</faultstring><faultactor>BKD webservices</faultactor><detail></detail></SOAP-ENV:Fault></SOAP-ENV:Body></SOAP-ENV:Envelope><LF>
    Wat voor mij belangrijk is, is de melding van die geldige datum. Als ik dezelfde xml via SoapUI verstuur, krijg ik ook die melding terug. Dan lijkt het mij dat ik een goede verbinding naar de webservices heb.

    Heb ik dan de verbinding goed gemaakt (lees : vraag bevestiging) ?
    Delphi is great. Lazarus is more powerfull

  15. #15
    Je krijgt een zinvol antwoord terug, dus je hebt inderdaad een technisch OK bericht gepost. De reactie die je krijgt gaat om de inhoud.
    Marcel

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •