19. Juli 2017 08:50
Hallo,
ich stehe vor folgendem Problem.
Ich möchte einen WebService im NAV erstellen der eine XML Empfangen, verarbeitet und auch anschließend wieder eine XML zurückschicken kann (Es muss über eine Codeunit geschehen).
Nun stell ich mir die Frage, wie ich eine XML empfangen soll, die sich mehrfach wdh. kann.
<Root>
<wdh />
<wdh />
<Root>
Hat da jemand evtl. eine Idee?
Zuletzt geändert von pjung am 21. Juli 2017 10:42, insgesamt 1-mal geändert.
19. Juli 2017 09:22
Ich hab mal gehört, dass man einen XMLPort schreiben soll und diesen dann als Parameter mit dem Haken VAR in der Webservice Funktion hinterlegen soll. Dann hast du die gewünschte Struktur, dass du mehrere Elemente empfangen und auch zurücksenden kannst.
Testen kann man das Ganze dann mit SOAPUI.
Alle Angaben ohne Gewähr... Ich habe es nie selber getestet :)
19. Juli 2017 15:10
Hallo,
das mit dem XMLPort ist in meinem Fall leider nicht praktikabel
weil die Antwort XML anders ausehen muss und ich jetzt nicht für das Zwischenspeichern der Werte in der XML über eine Table gehen wollte.
Ich hatte mir eher vorgestellt
Ich könnte das XML mit der XML Buffer Table verarbeiten.
aber dazu bräuchte ich die übermittelte XML entweder als Text oder als File.
Und die XML mittels TEXT Variable an den WebService zu übergeben ist an der Stelle auch nicht wirkl. toll, denn dann müsste immer ein CDATA vorne dran. Was die Stelle, die die Anfrage stellt nicht kann bzw. nur über einen Umweg kann.
19. Juli 2017 16:38
Hi,
hier wäre die Frage, welche Version von NAV es betrifft?
Ich empfehle dir via DotNet zu arbeiten:,
CreateXMLDocument(VAR XMLDoc : DotNet "MSXML.DOMDocumentClass";ProcInstruction : Text[1024];Async : Boolean)
CLEAR(XMLDoc);
IF ISNULL(XMLDoc) THEN
XMLDoc := XMLDoc.DOMDocumentClass;
XMLDocProcInst := XMLDoc.createProcessingInstruction('xml',ProcInstruction);
DOMNode := XMLDoc.appendChild(XMLDocProcInst);
XMLDoc.async(Async);
AddChildNode(VAR XMLDoc : DotNet "MSXML.DOMDocumentClass";VAR ParentNode : DotNet "MSXML.IXMLDOMNode";NodeName : Text[80];ExpandType : 'None,Next,Before';BeforeSteps : Integer;Value : Text[1024])
ChildNode := XMLDoc.createNode(1,NodeName,'');
ParentNode.appendChild(ChildNode);
IF Value <> '' THEN BEGIN
DomTextNode := XMLDoc.createTextNode(Value);
ChildNode.appendChild(DomTextNode);
END;
CASE ExpandType OF
ExpandType::Next:
BEGIN
ParentNode := ChildNode;
END;
ExpandType::Before:
BEGIN
FOR i := 1 TO BeforeSteps DO BEGIN
ParentNode := ParentNode.parentNode;
END;
END;
END;
Hier dann der Aufruf:
CreateXMLDocument(XMLDoc,'version="1.0" encoding="UTF-8"',FALSE);
DOMNode := XMLDoc.createNode(1,'root','');
XMLDoc.appendChild(DOMNode);
REPEAT
AddChildNode(XMLDoc,DOMNode,'elementHead',1,0,'');
AddChildNode(XMLDoc,DOMNode,'elementBody1',0,0,Wert1;
AddChildNode(XMLDoc,DOMNode,'elementBody2',0,0,Wert2);
UNTIL DeineTabelle.NEXT = 0;
Name DataType Subtype Length
XMLDoc DotNet MSXML.DOMDocumentClass.'Microsoft.MSXML, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'
Name DataType Subtype Length
DOMNode DotNet MSXML.IXMLDOMNode.'Microsoft.MSXML, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'
usw.
VG
19. Juli 2017 17:11
Speedstream hat geschrieben:hier wäre die Frage, welche Version von NAV es betrifft?
die Version müsste 2017 sein - sofern er es im richtigen Unterforum eingestellt hat.
Aber dein Ansatz über .Net würde ich ebenfalls empfehlen.
pjung hat geschrieben:aber dazu bräuchte ich die übermittelte XML entweder als Text oder als File.
ja - wo ist da das Problem?
20. Juli 2017 07:20
Also entweder ich verstehe den Ansatz nicht so ganz oder ich habe mich missverständlich ausgedrückt.
Also nochmal mein Problem.
Ich möchte in NAV ein WebService erstellen der eine XML erhält und auch eine Antwort in Form einer XML zurückschickt.
Was nicht geht ist
- Code:
CodeUnit
Function WebService(XMLParameter : Text)
wenn ich nämlich die XML als Text an NAV übermitteln möchte müsste ich sich bei dem WebService aufruf ja wie folgt aussehen
- Code:
<XMLParameter><![CDATA[<xml>...</xml>]]></XMLParameter>
und das CDATA möchte ich vermeiden, da die Stelle die den NAV WebService aufruft. Das CDATA nur mit einem deutl. mehr Aufwand mit übermitteln könnte.
Daher stelle ich mir die Frage, ob es in NAV evtl. einen einfacheren Weg gibt.
und wenn ich das Richtig verstanden habe ist der von Speedstream vorgeschlagene DotNet Ansatz ja zum erstellen einer XML.
Oder habe ich das falsch verstanden?
20. Juli 2017 08:27
pjung hat geschrieben:und wenn ich das Richtig verstanden habe ist der von Speedstream vorgeschlagene DotNet Ansatz ja zum erstellen einer XML.
Oder habe ich das falsch verstanden?
fast - du kannst damit XML lesen und schreiben
20. Juli 2017 08:40
Ja gut,
aber mein Problem ist ja nicht das lesen der XML
sondern wie ich NAV eine Webservice einrichte der so eine XML entgegennehmen kann
- Code:
<Root>
<!-- wdh kann sich mehrfach wiederholen -->
<wdh />
<wdh />
<Root>
und ohne das ich ihn so übermitteln müsste
- Code:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:test="urn:microsoft-dynamics-schemas/codeunit/Test">
<soapenv:Header/>
<soapenv:Body>
<test:XMLTest>
<test:xml><![CDATA[<xml><root><wdh /><wdh /></root>]]></test:xml>
</test:XMLTest>
</soapenv:Body>
</soapenv:Envelope>
So ganz habe ich nicht verstanden wie ich das mittels Dotnet bewerkstelligen soll.
Weil doch ein DotNet Parameter in einem WebService von NAV nicht funktioniert
oder irre ich mich?
20. Juli 2017 08:47
Ja der Code ist für die Erstellung der XML.
Diese kannst du dann mit XMLHttp.send(XMLDoc); an deinen externen Webservice geben.
Falls du eine Antwort bekommst kannst du diese dann via XMLDoc.loadXML(XMLHttp.responseText); abrufen und entsprechend verarbeiten.
Du kannst in deine XMLDoc auch direkt deine SOAP Request schreiben und dann via XMLHttp.send(XMLDoc) senden:
IF ISNULL(XMLHttp) THEN
XMLHttp := XMLHttp.XMLHTTPRequestClass;
IF ISNULL(XMLDoc) THEN
XMLDoc := XMLDoc.DOMDocumentClass;
XMLHttp.open('POST',<Webservice URL>,0,0,0);
XMLHttp.setRequestHeader('Host','xyz'); // bei Bedarf
XMLHttp.setRequestHeader('Content-type','text/xml');
// Beispiel einer SOAP Request
XMLHttp.setRequestHeader('SOAPAction',<WebserviceAction>);
XMLDoc.loadXML(
'<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>' +
'<Funktion>' +
'<Parameter1>' + Parameter1 + '</Parameter1>' +
'</Funktion>' +
'</soap:Body>' +
'</soap:Envelope>');
20. Juli 2017 08:51
Achso Ihr habt mich dann wohl missverstanden
ich will mit Navision keinen Webservice konsumieren sondern einen Zurverfügungstellen.
20. Juli 2017 09:47
Du kannst über Codeunits, Pages & Queries Komponenten aus NAV via Webservice zur Verfügung stellen.
Hierfür müssen diese in die Tabelle 2000000076 "Web Service" entsprechend eingetragen werden.
Wie genau die Objekte zu designen sind, kommt auf deinen Fall an.
Dann muss dein Service Tier entsprechend für SOAP Services konfiguriert sein.
Du müsstest dann auch z.B. bei der Page über Info zu dieser Seite im Berei URLs deine SOAP Url einsehen können...
20. Juli 2017 10:05
Das wiederum ist auch nicht mein Problem.
Den Webservice usw. ist eingerichtet.
Ich weiß nur nicht wie die Funktion in der als WebService eingerichtet CodeUnit bewerkstellige das er eine Komplette XML
mit wiederholenden Elementen
empfangen und verarbeiten kann und dann eine XML auch wieder als Antwort zurückgeben kann.
20. Juli 2017 10:16
ok, da kenne ich auch nur die Lösung als XMLPort via Parameter...
20. Juli 2017 12:38
Hallo,
Warum muss bei Text alles in CDATA eingebettet sein?
Hier ein Weg, den wir einsetzen.
- Code:
Name DataType Subtype Length
TempBlob Record TempBlob
XMLDomRequest DotNet System.Xml.XmlDocument.'System.Xml, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'
XMLDomResponse DotNet System.Xml.XmlDocument.'System.Xml, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'
WriteStream OutStream
ReadStream InStream
// Hauptfunktion der Codeunit
Process(Request : BigText;VAR Response : BigText)
WITH TempBlob DO BEGIN
INIT;
Blob.CREATEOUTSTREAM(WriteStream);
Request.WRITE(WriteStream);
Blob.CREATEINSTREAM(ReadStream);
END;
XMLDomRequest := XMLDomRequest.XmlDocument();
XMLDomRequest.Load(ReadStream);
// ... Verarbeitung
CLEAR(XMLDomRequest);
WITH TempBlob DO BEGIN
DELETEALL;
INIT;
Blob.CREATEOUTSTREAM(WriteStream);
WriteStream.WRITETEXT(XMLDomResponse.InnerXml);
CLEAR(XMLDomResponse);
Blob.CREATEINSTREAM(ReadStream);
Response.READ(ReadStream);
END;
Grüße
20. Juli 2017 13:26
@Ermac
Habt ihr evtl. einen Proxy vorne dran, der das ganze Serializiert?
Denn warum der Text alles in CDATA eingebettet sein muss ist ja damit er die
als Parameter übergebene XML vom Rest trennen kann
sonst würde es ja so aussehen
- Code:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:test="urn:microsoft-dynamics-schemas/codeunit/Test">
<soapenv:Header/>
<soapenv:Body>
<test:XMLTest>
<test:xml><xml><root><wdh /><wdh /></root></xml></test:xml>
</test:XMLTest>
</soapenv:Body>
</soapenv:Envelope>
21. Juli 2017 10:44
Gut also so wie sich das ganze für mich jetzt dargestellt hat.
Wenn man keinen Proxy (der die Daten serialisiert) vor das NAV setzten möchte,
bekommt man die von mir gewünschte XML Struktur tatsächlich nur mittels XMLPort hin.
In dem man dann die XML Buffer Table einfach mittels dem XMLPort befüllt und anschließend kann man dann mit der XML Buffer Table normal weiterarbeiten.
Beim Exportieren macht man das gleiche spielchen nur rückwärts
22. April 2021 15:17
Hallo,
ich weiß, dass dieses Thema schon älter ist. Aber ich habe genau das gleiche Problem und den Lösungsansatz nicht ganz verstanden.
Vorab 99,99999% aller Lösungsvorschläge die via Internetsuche gefunden werden können, beziehen sich auf den Konsum von externen Webservice.
Bei mir geht es, wie bei pjung, um das Bereitstellen eines Service mit einer komplexen Antwort. Viele Beispiele, wie eine Antwort aussehen kann, bezeiehen sich auf einzelne Werte und sind auch leicht umzusetzen.
Aber bei mir geht es nun ebenso um komplette XML Antworten.
Irgendwie bin ich überrascht, dass dieser Anwendungsfall scheinbar selten bis nie vorkommt.
23. April 2021 13:49
LandorCaeyran hat geschrieben:Irgendwie bin ich überrascht, dass dieser Anwendungsfall scheinbar selten bis nie vorkommt.
kannst du einfach mal beschreiben, was für einen Anwendungsfall du hast, wie die "komplexe" Antwort aussehen soll und wenn möglich, auf welchen Aufruf die Antwort erfolgen soll?
23. April 2021 14:03
Sehr gerne.
Anfrage:
- Code:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:com="http://com.domain.tld/">
<soapenv:Header/>
<soapenv:Body>
<com:Identification>
<com:Systemnumber>999</com:Systemnumber>
<com:Identifier>1234567890</com:Identifier>
</com:Identification>
</soapenv:Body>
</soapenv:Envelope>
Antwort:
- Code:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:com="http://com.domain.tld/">
<soapenv:Header/>
<soapenv:Body>
<com:MultipayImport>
<com:Header>
<com:Timestamp>2020-12-02T12:14:38</com:Timestamp>
<com:Currency>EUR</com:Currency>
<com:SystemMessage>Success</com:SystemMessage>
</com:Header>
<com:Orders>
<com:Order>
<com:ExternalReference>123456</com:ExternalReference>
<com:TotalAmount>330.00</com:TotalAmount>
<com:ExternalData>4</com:ExternalData>
<com:UserReference>100</com:UserReference>
<com:TextFields>
<com:TextField Id="0">1111111</com:TextField>
<com:TextField Id="1">2222222</com:TextField>
</com:TextFields>
<com:OrderCategoryId>XXX</com:OrderCategoryId>
<com:Items>
<com:Item>
<com:Id>1</com:Id>
<com:Amount>330.00</com:Amount>
<com:Count>1</com:Count>
</com:Item>
</com:Items>
</com:Order>
</com:Orders>
</com:MultipayImport>
</soapenv:Body>
</soapenv:Envelope>
Die Anzahl der Parameter in der Anfrage sind fix. Damit fällt die Rückgabe via parameter XMLPOrt mit var aus.
Ich werde aber dennoch mal versuchen, den Lieferanten eine Anpassung seiner Anfrage abzuringen.
23. April 2021 16:09
ah - also wie in deinem anderen Beitrag
23. April 2021 16:36
Ja.
Hatte mich hier mal angehangen, weil es exakt die gleiche Fragestellung war.
Nur konnte der Themenersteller wohl am Ende doch mit einer Änderung weiter arbeiten...
13. Mai 2021 21:23
Hallo,
gab es da jetzt eine Lösung ? Ich habe dasselbe Problem.
Möchte mit einem NAV-Webservice (Codeunit) XML empfangen und auf wieder zurückgeben.
Das CDATA möchte ich vermeiden und bei der Rückgabe des XML werden die < und > auch noch in < und > umgesetzt.
Da muss es doch etwas geben !?
Für XMLPorts ist die eingehende und dann ausgehende Struktur zu aufwendig
Danke für die Tipps
Powered by phpBB © phpBB Group.
phpBB Mobile / SEO by Artodia.