SOAP Connector: Verbindung Navision - Webservice

21. September 2007 10:31

Hi,

wir pruefen derzeit, wie wir eine Webservice Abfrage mittels "SOAP" realisieren koennen. Konkret soll dieses Programm abgeloest werden.
Die Infos, die ich bis jetzt gefunden habe, waren leider alle recht allgemein gehalten.

Hat von euch jemand damit schon gearbeitet? Koennt ihr mir vielleicht mit Code-Beispielen dienen? :oops:
Gibt es etwas spezielles zu beachten?


Danke & Gruesse
feri

21. April 2008 09:52

Warum unbedingt SOAP, warum kein Webservice?
SOAP hat einen ziemlichen Daten-Overload.
Meistens geht es doch in Verbindung mit Navision um eine Realisierung mit einer Drittapplikation, deren Schnittstelle man im Projekt abstimmt, so dass Webservice performanter sind, als SOAP.

21. April 2008 14:17

Hi,

die Schnittstelle besteht schon seit einiger Zeit, wird von anderer Seite bereits verwendet und ist somit auch fixiert. :wink:

Aus zeitlichen Gruenden hat sich das alles jetzt etwas verschoben. Vermutlich werden wir das jetzt auch nicht direkt im Navision machen sondern mit einer in VB erstellten DLL.

Gruesse
feri

19. Juni 2008 16:52

Hi,

Wir nutzen die Microsoft SOAP.dll und die XML.dll. Folgender Code zeigt einen einfachen Aufbau einer Anfrage. Funktioniert in beide Richtungen und ist sehr stabil.

Gruß

Code:
CLEAR(locautXmlDoc);
CLEAR(locautSoapHttpConnector);
CLEAR(locautSoapSerializer);


CREATE(locautSoapHttpConnector);
locautSoapHttpConnector.Property('EndPointURL', recSteuerdaten.WSDLAdresse);
locautSoapHttpConnector.Connect;
locautSoapHttpConnector.Property('AuthUser', recSteuerdaten.User);
locautSoapHttpConnector.Property('AuthPassword', recSteuerdaten.Passwort);
locautSoapHttpConnector.Property('Timeout', 5 * 1000);
locautSoapHttpConnector.Property('SoapAction',recSteuerdaten.ServiceAdresse);
locautSoapHttpConnector.BeginMessage;

CREATE(locautSoapSerializer);
locautSoapSerializer.Init(locautSoapHttpConnector.InputStream);
locautSoapSerializer.startEnvelope('SOAP','STANDARD');
locautSoapSerializer.startBody;
locautSoapSerializer.startElement('NameDesService');

  locautSoapSerializer.startElement('login');
  locautSoapSerializer.writeString(recSteuerdaten.User);
  locautSoapSerializer.endElement;
 
  locautSoapSerializer.startElement('password');
  locautSoapSerializer.writeString(recSteuerdaten.Passwort);
  locautSoapSerializer.endElement;

locautSoapSerializer.endElement;
locautSoapSerializer.endBody;
locautSoapSerializer.endEnvelope;
locautSoapHttpConnector.EndMessage;

CREATE(locautXmlDoc);
  locautXmlDoc.load(locautSoapHttpConnector.OutputStream);
  //optional, speichern des XML Files
  locautXmlDoc.save('N:\XXX\'+Datumsformatierung+'_Getvt.xml');

XMLNodeList := locautXmlDoc.getElementsByTagName('item');
//MESSAGE(FORMAT(XMLNodeList.length));
FOR i := 0 TO XMLNodeList.length - 1 DO BEGIN
  XMLNode := XMLNodeList.item(i);
  XMLNode2 := XMLNode.selectSingleNode('Nodename');
    IF XMLNode2.text <> ''
      THEN BEGIN
        ANWEISUNG
      End;     
END;

CLEAR(locautXmlDoc);
CLEAR(locautSoapHttpConnector);
CLEAR(locautSoapSerializer);
 

20. Juni 2008 12:34

Hallo MrAbbey,

ich hab da mal eine Frage.
Ich beschäftige mich zurzeit auch mit dem Abrufen eines Webservices.
Allerdings bekomme ich den Aufbau der Abfrage nicht hin (Antwort des Webservice-Servers sagt immer, dass kein Value übergeben wurde).

Kann ich mir nach Erstellung den Inhalt des
locautSoapSerializer oder des locautSoapHttpConnector
irgendwie als reines XML File anzeigen lassen um so zu kontrollieren, ob meine Anfrage die geforderte XML Struktur enthält?

Was ich möchte ist eigentlich ganz einfach:

Ich möchte zum Test die Funktion "Translate" von webservicex.net aus NAV aufrufen. Der Soap-Request soll lt. webservicex.net so aussehen:

Code:
POST /TranslateService.asmx HTTP/1.1
Host: www.webservicex.net
Content-Type: text/xml; charset=utf-8
Content-Length: length
SOAPAction: "http://www.webservicex.net/Translate"

<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
  <soap:Body>
    <Translate xmlns="http://www.webservicex.net">
      <LanguageMode>EnglishTOGerman</LanguageMode>
      <Text>string</Text>
    </Translate>
  </soap:Body>
</soap:Envelope>


Mein code sieht folgendermaßen aus:

Code:
CREATE(locautSoapHttpConnector);
locautSoapHttpConnector.Property('EndPointURL', http://www.webservicex.net/TranslateService.asmx');

locautSoapHttpConnector.Connect;
locautSoapHttpConnector.Property('AuthUser', 'User');
locautSoapHttpConnector.Property('AuthPassword', 'Password');
locautSoapHttpConnector.Property('Timeout', 5 * 1000);

locautSoapHttpConnector.Property('SoapAction','http://www.webservicex.net/Translate');
locautSoapHttpConnector.BeginMessage;

CREATE(locautSoapSerializer);
locautSoapSerializer.Init(locautSoapHttpConnector.InputStream);
locautSoapSerializer.startEnvelope('SOAP','STANDARD');
locautSoapSerializer.startBody;

locautSoapSerializer.startElement('Translate');
  locautSoapSerializer.startElement('LanguageMode');
    locautSoapSerializer.writeString('EnglishTOGerman');
  locautSoapSerializer.endElement;
  locautSoapSerializer.startElement('Text');
    locautSoapSerializer.writeString('master');
  locautSoapSerializer.endElement;
locautSoapSerializer.endElement;

locautSoapSerializer.endBody;
locautSoapSerializer.endEnvelope;
locautSoapHttpConnector.EndMessage;

CREATE(locautXmlDoc);
locautXmlDoc.load(locautSoapHttpConnector.OutputStream);
locautXmlDoc.save('c:\temp1.xml');


Als Antwort erhalte ich von webservicex.net:

Code:
  <?xml version="1.0" encoding="utf-8" ?>
- <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">
- <soap:Body>
- <TranslateResponse xmlns="http://www.webservicex.net">
  <TranslateResult>Value cannot be null. Parameter name: translationmode</TranslateResult>
  </TranslateResponse>
  </soap:Body>
  </soap:Envelope>


Was mache ich falsch? Sehe wohl den Wald vor lauter Bäumen nicht, oder ???

24. Juni 2008 16:22

Ich nochmal,

habe mir das freie Tool "soapUI" besorgt, die WSDL Datei mit der Schnittstellenbeschreibung dort hinein geladen und mir die möglichen Requests erzeugen lassen.
Diese Requests habe ich dann mit einem XMLPort nachgebildet.
Das ganze dann mit einem POST abgeschickt und nun klappt es auch.

Gruß,
naviii

Re: SOAP Connector: Verbindung Navision - Webservice

9. Dezember 2010 11:54

Hallo zusammen,

ich möchte den Thread wieder aus der Versenkung holen. Ich habe das gleiche Problem, wie Naviii.
Nur möchte ich ungerne die Realisierung über XMl-Ports durchführen. Da ich plane mehrere Webservices anzusprechen und ungern jede Menge XML-Ports haben möchte.
Hat jemand noch eine Idee, oder einen Tipp?

Code:

    CLEAR(locautXmlDoc);
    CLEAR(locautSoapHttpConnector);
    CLEAR(locautSoapSerializer);


    CREATE(locautSoapHttpConnector);
    locautSoapHttpConnector.Property('EndPointURL', 'http://www.webservicex.net/TranslateService.asmx');
    locautSoapHttpConnector.Connect;
    locautSoapHttpConnector.Property('Timeout', 5 * 1000);
    locautSoapHttpConnector.Property('SoapAction','http://www.webservicex.net/Translate');
    locautSoapHttpConnector.BeginMessage;

    CREATE(locautSoapSerializer);
    locautSoapSerializer.Init(locautSoapHttpConnector.InputStream);
    locautSoapSerializer.StartEnvelope('SOAP','STANDARD');
    locautSoapSerializer.StartBody;
    locautSoapSerializer.StartElement('EnglishTOGerman');

      locautSoapSerializer.StartElement('Text');
      locautSoapSerializer.WriteString('Hello');
      locautSoapSerializer.EndElement;

    locautSoapSerializer.EndElement;
    locautSoapSerializer.EndBody;
    locautSoapSerializer.EndEnvelope;
   CLEAR(locautXmlDoc);

    locautSoapHttpConnector.EndMessage;


    CREATE(locautXmlDoc);
      locautXmlDoc.load(locautSoapHttpConnector.OutputStream);

      locautXmlDoc.save('c:\testxmloutput1.xml');

    CLEAR(locautXmlDoc);
    CLEAR(locautSoapHttpConnector);
    CLEAR(locautSoapSerializer);


Die Antwort sieht wie folgt aus:

Code:
<soap:Envelope>
<soap:Body>
<TranslateResponse>
<TranslateResult>
Value cannot be null.
Parameter name: translationmode
</TranslateResult>
</TranslateResponse>
</soap:Body>
</soap:Envelope>


Gruß

Christian

Re: SOAP Connector: Verbindung Navision - Webservice

10. Dezember 2010 10:24

Hi cdziewas,

hast Du das Tool "SoapUI" mal ausprobiert?
Damit kann man ganz flexibel die Inhalte des abzusendenden Request ändern und testen, was jeweils als Webservice Antwort im XML File zurückkommt.

Gruß,
naviii

[gelöst] Re: SOAP Connector: Verbindung Navision - Webservic

10. Dezember 2010 13:10

Hi Naviii,

danke. Das habe ich. Konnte jetzt gerade auch mittel den Automations eine gültige Anfrage senden und bekam ein verwertbares Response.
Musste das wegen den Namespaces umstellen. Ich nutze nun nicht mehr das SOAP-Toolkit, sondern die Microsoft XML dlls.
Klappt wunderbar und die Antwortzeit ist auch voll ok.
Musste bei der Rückmeldung ein wenig tricksen. Daher sind die Variablen noch nicht aufgeräumt.
Aber Evtl. hilft einem das kleine Beispiel weiter.

Code:

{
Name   DataType   Subtype   Length
XMLDOMDocument   Automation   'Microsoft XML, v5.0'.DOMDocument50   
XMLDOMDocument2   Automation   'Microsoft XML, v5.0'.DOMDocument50   
CurrNode   Automation   'Microsoft XML, v5.0'.IXMLDOMNode   
BaseNode   Automation   'Microsoft XML, v5.0'.IXMLDOMNode   
NewChild   Automation   'Microsoft XML, v5.0'.IXMLDOMNode   
XMLDOMManagement   Codeunit   XML DOM Management   
DocNameSpace   Text      200
locautXmlHttp   Automation   'Microsoft XML, v5.0'.XMLHTTP   
LocXMLNodeList   Automation   'Microsoft XML, v5.0'.IXMLDOMNodeList   
LocXMLNode   Automation   'Microsoft XML, v5.0'.IXMLDOMNode   
ItemCount   Integer      
i   Integer      
 }

CLEAR(XMLDOMDocument);
CLEARALL;
IF NOT CREATE(XMLDOMDocument) THEN
 EXIT;
XMLDOMDocument.loadXML := '<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"/>';
CurrNode := XMLDOMDocument.documentElement;
DocNameSpace := 'http://schemas.xmlsoap.org/soap/envelope/';

WITH XMLDOMManagement DO BEGIN
 XMLDOMManagement.SetNormalCase;

     IF AddElement(CurrNode,'soapenv:Header','',DocNameSpace,NewChild) > 0 THEN
       EXIT;     
     IF AddElement(CurrNode,'soapenv:Body','',DocNameSpace,NewChild) > 0 THEN
       EXIT;
       CurrNode := NewChild;
       DocNameSpace :='weiterer Namespace';
     IF AddElement(CurrNode,'nav:GetLoginFromRegNr','',DocNameSpace,NewChild) > 0 THEN
       EXIT;
       CurrNode := NewChild;
     IF AddElement(CurrNode,'nav:regNr','Daten',DocNameSpace,NewChild) > 0 THEN
       EXIT;
    END;



CREATE(locautXmlHttp);
locautXmlHttp.open('POST','http://url des Services/Service.asmx',0);
locautXmlHttp.setRequestHeader('Content-type','text/xml');
locautXmlHttp.setRequestHeader('charset','utf-8');   
locautXmlHttp.setRequestHeader('SOAPAction','url des speziellen Dienstes');

locautXmlHttp.send(XMLDOMDocument);
IF ISCLEAR(XMLDOMDocument2) THEN
   CREATE(XMLDOMDocument2);
XMLDOMDocument2.async := FALSE;
XMLDOMDocument2.load(locautXmlHttp.responseXML);


IF locautXmlHttp.status = 200 THEN BEGIN
  LocXMLNode := XMLDOMDocument2.documentElement();
  i := 0;
  REPEAT
    i += 1;
    LocXMLNode :=  LocXMLNode.firstChild;
  UNTIL (LocXMLNode.nodeName = 'Error') OR (i = 20);

  IF  LocXMLNode.text ='Success' THEN BEGIN
    MESSAGE(FORMAT(LocXMLNode.text));
    //Zum Tag Login springen
      LocXMLNode := LocXMLNode.nextSibling;
      MESSAGE(LocXMLNode.nodeName);
      //Liste der Tags unter Login
      LocXMLNodeList := LocXMLNode.childNodes;
      ItemCount := LocXMLNodeList.length;
      MESSAGE(FORMAT(ItemCount));
      LocXMLNode := LocXMLNode.firstChild;

  END ELSE BEGIN
    MESSAGE(FORMAT( LocXMLNode.text));
  END;
END ELSE BEGIN
  MESSAGE('%1', locautXmlHttp.status);
END;
 CLEARALL;



Gruß

Christian

Re:

11. November 2011 10:24

Hi Leute,

sorry, dass ich dieses alte Thema nochmal ausgrabe...
Ich möchte gerne mit Navision auf Mantis Tickets aus dem Web zugreifen. Mantis bietet dafür eine Soap schnittstelle.
Nun suche ich einen Weg wie ich die Daten über Soap nach Navision bekommen kann. Leider habe ich keine Ahnung von Soap, habe aber schon eine Beispiel Datei, bzw dieses Beispiel von MrAbbey gefunden.
Allerdings fehlt mir irgendwie die soap.dll von der er spricht.
Diese drei Controls
CLEAR(locautXmlDoc);
CLEAR(locautSoapHttpConnector);
CLEAR(locautSoapSerializer);
werden bei mir nicht erkannt, und ich weiss nicht, wo ich die entsprechende DLL finden kann.
Irgend so ein Soap Toolkit 3.0 von Microsoft habe ich mir auch schon installiert, in den Benutzerdefinierten Controls finde ich aber immer noch nichts, was auf soap hindeutet.

Gruß Tobias

MrAbbey hat geschrieben:Hi,

Wir nutzen die Microsoft SOAP.dll und die XML.dll. Folgender Code zeigt einen einfachen Aufbau einer Anfrage. Funktioniert in beide Richtungen und ist sehr stabil.

Gruß

Code:
CLEAR(locautXmlDoc);
CLEAR(locautSoapHttpConnector);
CLEAR(locautSoapSerializer);


CREATE(locautSoapHttpConnector);
locautSoapHttpConnector.Property('EndPointURL', recSteuerdaten.WSDLAdresse);
locautSoapHttpConnector.Connect;
locautSoapHttpConnector.Property('AuthUser', recSteuerdaten.User);
locautSoapHttpConnector.Property('AuthPassword', recSteuerdaten.Passwort);
locautSoapHttpConnector.Property('Timeout', 5 * 1000);
locautSoapHttpConnector.Property('SoapAction',recSteuerdaten.ServiceAdresse);
locautSoapHttpConnector.BeginMessage;

CREATE(locautSoapSerializer);
locautSoapSerializer.Init(locautSoapHttpConnector.InputStream);
locautSoapSerializer.startEnvelope('SOAP','STANDARD');
locautSoapSerializer.startBody;
locautSoapSerializer.startElement('NameDesService');

  locautSoapSerializer.startElement('login');
  locautSoapSerializer.writeString(recSteuerdaten.User);
  locautSoapSerializer.endElement;
 
  locautSoapSerializer.startElement('password');
  locautSoapSerializer.writeString(recSteuerdaten.Passwort);
  locautSoapSerializer.endElement;

locautSoapSerializer.endElement;
locautSoapSerializer.endBody;
locautSoapSerializer.endEnvelope;
locautSoapHttpConnector.EndMessage;

CREATE(locautXmlDoc);
  locautXmlDoc.load(locautSoapHttpConnector.OutputStream);
  //optional, speichern des XML Files
  locautXmlDoc.save('N:\XXX\'+Datumsformatierung+'_Getvt.xml');

XMLNodeList := locautXmlDoc.getElementsByTagName('item');
//MESSAGE(FORMAT(XMLNodeList.length));
FOR i := 0 TO XMLNodeList.length - 1 DO BEGIN
  XMLNode := XMLNodeList.item(i);
  XMLNode2 := XMLNode.selectSingleNode('Nodename');
    IF XMLNode2.text <> ''
      THEN BEGIN
        ANWEISUNG
      End;     
END;

CLEAR(locautXmlDoc);
CLEAR(locautSoapHttpConnector);
CLEAR(locautSoapSerializer);
 

Re: SOAP Connector: Verbindung Navision - Webservice

28. Dezember 2011 12:33

ok ich bin jetzt schon etwas weiter, ich habe die automations gefunden, auch wenn die immer ein parameter mehr brauchen als im beispiel.
locautSoapHttpConnector 'Microsoft Soap WinHttp Connector Type Library (v3.0)'.WinHttpConnector30
locautSoapSerializer 'Microsoft Soap WinHttp Connector Type Library (v3.0)'.ISoapSerializer

Aber wie bekomme ich dieses schema jetzt in navision rein? Ich verstehe leider nicht wie das in navisison mit startelement, startbody usw. zusammengesetzt werden muss.
Code:
<soapenv:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:man="http://futureware.biz/mantisconnect">
   <soapenv:Header/>
   <soapenv:Body>
      <man:mc_issue_get_biggest_id soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
         <username xsi:type="xsd:string">Administrator</username>
         <password xsi:type="xsd:string">root</password>
         <project_id xsi:type="xsd:integer">1</project_id>
      </man:mc_issue_get_biggest_id>
   </soapenv:Body>
</soapenv:Envelope>

und in welcher form bekomme ich die antwort? mit soapUi bekomme ich folgendes:
Code:
<SOAP-ENV:Envelope SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" 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>
      <ns1:mc_issue_get_biggest_idResponse xmlns:ns1="http://futureware.biz/mantisconnect">
         [color=#FF0000]<return xsi:type="xsd:integer">5</return>[/color]
      </ns1:mc_issue_get_biggest_idResponse>
   </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

idealerweise möchte ich natürlich erstmal nur eine message die mir die 5 ausgibt.