POST /DataService.asmx HTTP/1.1 Host: fat-aardvark.net Content-Type: text/xml; charset=utf-8 SOAPAction: "http://tempuri.org/SelectData" <?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> <SelectData xmlns="http://tempuri.org/" /> </soap:Body> </soap:Envelope>
HTTP/1.1 200 OK Content-Type: text/xml; charset=utf-8 Content-Length: length <?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> <SelectDataResponse xmlns="http://tempuri.org/"> <SelectDataResult> <Data> <ID>int</ID> <Code>int</Code> <Type>int</Type> <Name>string</Name> </Data> <Data> <ID>int</ID> <Code>int</Code> <Type>int</Type> <Name>string</Name> </Data> </SelectDataResult> </SelectDataResponse> </soap:Body> </soap:Envelope>
TagName TagType SourceType DataSource soap:Envelope Element Text <soap:Envelope> xmlns:soap Attribute Text NS1 xmlns:xsi Attribute Text NS2 xmlns:xsd Attribute Text NS3 soap:Body Element Text <soap:Body> SelectData Element Text <SelectData> xmlns Attribute Text NS4
Name ConstValue NSpace1 http://schemas.xmlsoap.org/soap/envelope/ NSpace2 http://www.w3.org/2001/XMLSchema-instance NSpace3 http://www.w3.org/2001/XMLSchema NSpace4 http://tempuri.org/
OnPreXMLport() NS1 := NSpace1; NS2 := NSpace2; NS3 := NSpace3; NS4 := NSpace4;
TagName TagType SourceType DataSource Envelope Element Text <Envelope> Body Element Text <Body> SelectDataResponse Element Text <SelectDataResponse> SelectDataResult Element Text <SelectDataResult> Data Element Text <Data> ID Element Text D1 Code Element Text D2 Type Element Text D3 Name Element Text D4
Name DataType Subtype XP1 XMLport <name of the first XMLport> XP2 XMLport <name of the second XMLport> XMLDoc Automation 'Microsoft XML, v5.0'.DOMDocument XMLHttpConn Automation 'Microsoft XML, v5.0'.ServerXMLHTTP InStr InStream OutStr OutStream
Name DataType Subtype TempTable Record TempBlob (set this as a temporary table!)
Var Name DataType Subtype No Source Automation 'Microsoft XML, v5.0'.DOMDocument Yes Destination Automation 'Microsoft XML, v5.0'.DOMDocument
Name DataType Subtype TempTable Record TempBlob (set this as a temporary table!) XMLStyleSheet Automation 'Microsoft XML, v5.0'.DOMDocument StyleOutStr OutStream StyleInStr InStream
====================================================== OnRun() ====================================================== SendMessage; ====================================================== SendMessage() ====================================================== //setup the temporary table so that we can handle the XML without saving it to disk first //create a couple of streams to transfer the data in and out of the BLOB field CLEAR(TempTable); TempTable.Blob.CREATEINSTREAM(InStr); TempTable.Blob.CREATEOUTSTREAM(OutStr); //the request XMLport fills the BLOB with the XML message CLEAR(XP1); XP1.SETDESTINATION(OutStr); XP1.EXPORT; //load the message into the XML automation variable IF ISCLEAR(XMLDoc) THEN CREATE(XMLDoc); XMLDoc.load(InStr); //this is for diagnostics only, so you can see what the XMLport actually produced XMLDoc.save('C:\Temp\XMLRequest.txt'); //create the HTTP connector IF ISCLEAR(XMLHttpConn) THEN CREATE(XMLHttpConn); //tell it where the web service is located XMLHttpConn.open('POST','http://fat-aardvark.net/DataService.asmx',FALSE); //set some values in the request header depending on what the service requires XMLHttpConn.setRequestHeader('Host','fat-aardvark.net'); XMLHttpConn.setRequestHeader('SOAPAction','http://tempuri.org/SelectData'); XMLHttpConn.setRequestHeader('Content-Type','text/xml'); //actually send the message XMLHttpConn.send(XMLDoc); //get the response XMLDoc.load(XMLHttpConn.responseXML); //tell us if we got an error (it is 200 because the response definition said "200 OK") IF XMLHttpConn.status <> 200 THEN BEGIN MESSAGE('Status %1 %2',XMLHttpConn.status,XMLHttpConn.statusText); EXIT; END; //this is for diagnostics only, so you can see what you got back XMLDoc.save('C:\Temp\XMLResponse1.xml'); //take away the namespaces RemoveNamespace(XMLDoc,XMLDoc); //this is for diagnostics only, so you can see what it looks like after the namespaces have gone XMLDoc.save('C:\Temp\XMLResponse2.xml'); //fill the BLOB with the response XML XMLDoc.save(OutStr); //the response XMLport reads the data from the BLOB and processes it CLEAR(XP2); XP2.SETSOURCE(InStr); XP2.IMPORT; ====================================================== RemoveNamespace ====================================================== //this has been taken from a Microsoft knowledgebase aricle and strips out the //namespaces from an XML message using a style sheet TempTable.Blob.CREATEOUTSTREAM(StyleOutStr); TempTable.Blob.CREATEINSTREAM(StyleInStr); StyleOutStr.WRITETEXT('<?xml version="1.0" encoding="UTF-8"?>'); StyleOutStr.WRITETEXT('<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">'); StyleOutStr.WRITETEXT('<xsl:output method="xml" encoding="UTF-8" />'); StyleOutStr.WRITETEXT('<xsl:template match="/">'); StyleOutStr.WRITETEXT('<xsl:copy>'); StyleOutStr.WRITETEXT('<xsl:apply-templates />'); StyleOutStr.WRITETEXT('</xsl:copy>'); StyleOutStr.WRITETEXT('</xsl:template>'); StyleOutStr.WRITETEXT('<xsl:template match="*">'); StyleOutStr.WRITETEXT('<xsl:element name="{local-name()}">'); StyleOutStr.WRITETEXT('<xsl:apply-templates select="@* | node()" />'); StyleOutStr.WRITETEXT('</xsl:element>'); StyleOutStr.WRITETEXT('</xsl:template>'); StyleOutStr.WRITETEXT('<xsl:template match="@*">'); StyleOutStr.WRITETEXT('<xsl:attribute name="{local-name()}"><xsl:value-of select="."/></xsl:attribute>'); StyleOutStr.WRITETEXT('</xsl:template>'); StyleOutStr.WRITETEXT('<xsl:template match="text() | processing-instruction() | comment()">'); StyleOutStr.WRITETEXT('<xsl:copy />'); StyleOutStr.WRITETEXT('</xsl:template>'); StyleOutStr.WRITETEXT('</xsl:stylesheet>'); IF ISCLEAR(XMLStyleSheet) THEN CREATE(XMLStyleSheet); XMLStyleSheet.load(StyleInStr); IF ISCLEAR(Destination) THEN CREATE(Destination); Source.transformNodeToObject(XMLStyleSheet,Destination);
Comments
A link for more info would be appreciated..
Example 1: You are doing a telesales system and you want to validate a credit card and get an authorisation while the customer is on the phone. You find a credit card service provider and they give you details of their webservice. You send a request with the credit card details and they send you an authorisation number if the card is OK or an error if it is not. For this, you would have a form in NAV where you enter the details and then the user clicks a button to call this code. It takes the details they have entered and uses the first XMLport to format the request. The response XMLport then updates the payment details with the authorisation it receives.
Example 2: It is not uncommon for companies to want to trade through a website but they don't want the hassle of administering it themselves so they buy the service from a provider. The provider hosts & maintains the website and holds the data in their own database. You now need to get the orders from that database and keep the website updated with prices and stock levels. The provider gives you details of a webservice that you can use to read/write your data. You would then create a codeunit to run in NAS uses this code to periodically send a request for orders to the website which then responds with a list of orders that you import through the XMLport. Conversely, you format a request that tells the website how much stock you have of an item and the website responds with an acknowledgement.
This is all about consuming somebody else's webservice, not communicating with another NAV database (there maybe a NAV database behind the webservice but that isn't something that you need to know when you are consuming the service).
Cheers
John
Correct. It is a way of sending an XML file to a webservice and getting an XML file in return. That exchange may be you requesting something from the webservice or you telling the webservice to do something and it responds telling you that it has done it.
Cheers
John
Thanks for your detailed description on the xml port webservice caller.
Can you give us an example on how to make Navision work the other way around - as a webservice receiving request as xml documents from sockets and sending back answers ?
I did look into CU 7700, but can you please show me how to incorporate the NAS as a webservice with your example so that Navision is listening for the xml's and then replies with a new xml file to the request ?
I'm trying to use this with NAV 3.70. I ran into trouble when I got to:
Name DataType Subtype
TempTable Record TempBlob (set this as a temporary table!)
I can not find the subtype "TempBlob". Should I create this table? If so what filed(s) and properties should I give it?
MVP - Dynamics NAV
My BLOG
NAVERTICA a.s.
" This message is for C/AL programmers:
The call to member save failed. msxml3.dll returned the following message:
The system cannot find the path specified."
I have registered the msxml3.dll(SP7) using regsvr32, I have tried using the automation variable 'Microsoft XML, v6.0'.ServerXMLHTTP'
'Microsoft XML, v4.0'.ServerXMLHTTP' but could not found 'Microsoft XML, v5.0'.ServerXMLHTTP', considering the v4.0 , v5.0 as the version of xml, i tried looking for msxml5.0.dll as well but it says that it specifically meant for office products, which i don't have installed currently on my system.
So, My question is, "Is it important to use only 'Microsoft XML, v5.0'.ServerXMLHTTP" if yes do i need to have msxml5.dll
if not important then it means i can use other versions, then why i am getting the error of msxml3.dll
Your help will be highly appreciated.
Thanks
Chander
I am also facing the same error popping.
" This message is for C/AL programmers:
The call to member save failed. msxml3.dll returned the following message:
The system cannot find the path specified."
Can anyone tell what and why it is?
Thanks,
Aravindh
I have modified the Code a little bit like the following, but still i am getting an error.
//setup the temporary table so that we can handle the XML without saving it to disk first
//create a couple of streams to transfer the data in and out of the BLOB field
CLEAR(TempTable);
TempTable.Blob.CREATEINSTREAM(InStr);
TempTable.Blob.CREATEOUTSTREAM(OutStr);
//the request XMLport fills the BLOB with the XML message
CLEAR(XP1);
XP1.SETDESTINATION(OutStr);
XP1.EXPORT;
//load the message into the XML automation variable
IF ISCLEAR(XMLDoc) THEN
CREATE(XMLDoc,FALSE,TRUE);
XMLDoc.load(InStr);
//this is for diagnostics only, so you can see what the XMLport actually produced
XMLDoc.save('C:\Temp\XMLRequest.txt');
Microsoft Dynamics NAV
Streams cannot be used with client-side invoked automation objects.
OK
Any idea to solve this or is there a new version of this codes to work in nav 13 r2?
I am using dotnet assemblies to call webservices. Best is to not use automations at all in NAV 2013.
MVP - Dynamics NAV
My BLOG
NAVERTICA a.s.
I tried creating the tutorial. But there is no run and notified error: Streams không thể sử dụng với invoked automation objects-side client. -> at line XMLDoc.load (InStr);
If you have an example of this method please share.
Thanks very much
https://rockwithnav.wordpress.com/2016/02/23/consume-net-webservice-dotnet-data-type/
Blog - rockwithnav.wordpress.com/
Twitter - https://twitter.com/RockwithNav
Facebook - https://facebook.com/rockwithnav/