SOAP web services and NAV restrictions

Cem_Karaer
Member Posts: 281
Hello,
I have to find a way to consume 3rd party web services within NAV classic clients (5.0 to 2009). I found no mention of WCF usage within NAV in neither this forum nor anywhere else. So I decided to create proxy SOAP services first and then consume those services in NAV. I did consume SOAP web services thanks to the following entry:
http://www.mibuso.com/forum/viewtopic.php?f=23&t=1303
First I manually created the SOAP body, and use soap serializer's WriteXml functions. But here came the NAV limitation: can't use strings longer than 1024..
So I changed my mind and use serializer's StartElement, WriteString and EndElement functions. It did work well but.. I had to elaborate my code according to the structure of proxy services' web methods.
Then I changed my mind again and attempted to use XMLPorts. I thought that something with XML would be great for another thing based on XML. So I designed XMLPorts that can produce the exact response XML documents. But here came another obstacle: I can't use that beautiful XML with httpconnector (which is mentioned in the link)..
So I changed my mind again
and use XMLHTTP with open, setRequestHeader and send functions. It was really great until I collided to the same NAV limitation: can't use string longer than 1024 in the send() function.
What is the best way? Should I elaborate my code for each and every method or try to find a way for using the output of XMLPorts.
Note: The best way is to upgrade to 2013 and use RTC, but it is not possible for non-technical reasons.
I have to find a way to consume 3rd party web services within NAV classic clients (5.0 to 2009). I found no mention of WCF usage within NAV in neither this forum nor anywhere else. So I decided to create proxy SOAP services first and then consume those services in NAV. I did consume SOAP web services thanks to the following entry:
http://www.mibuso.com/forum/viewtopic.php?f=23&t=1303
First I manually created the SOAP body, and use soap serializer's WriteXml functions. But here came the NAV limitation: can't use strings longer than 1024..
So I changed my mind and use serializer's StartElement, WriteString and EndElement functions. It did work well but.. I had to elaborate my code according to the structure of proxy services' web methods.
Then I changed my mind again and attempted to use XMLPorts. I thought that something with XML would be great for another thing based on XML. So I designed XMLPorts that can produce the exact response XML documents. But here came another obstacle: I can't use that beautiful XML with httpconnector (which is mentioned in the link)..
So I changed my mind again

What is the best way? Should I elaborate my code for each and every method or try to find a way for using the output of XMLPorts.
Note: The best way is to upgrade to 2013 and use RTC, but it is not possible for non-technical reasons.
Cem Karaer @ Pargesoft
Dynamics NAV Developer since 2005
Dynamics NAV Developer since 2005
0
Comments
-
We had a similar situation on site (NAV 2009), and after a fair bit of trying and retrying, we decided to just write C# code to actually talk to the third party WS, and put it into a DLL that NAV could use as an automation object.
Two potential problems (aside from the obvious required experience with C# and writing automations):
1) The DLL needs to be deployed to every classic client machine that might use the WS
2) The automation references get confused if you recompile your DLL and let the compiler assign different GUIDs to your functions. Make sure that you manually assign GUIDs, and as much as possible, only add new functions to the end of your classes (which is abhorrent to people who like their code organized nicely, but better than having your NAV code calling random interfaces).
Once you are dealing with a COM interface for which you can define the parameters, you can work around most of the NAV restrictions by changing the interfaces a bit -- for example, if you really do need to read a single huge text field into NAV, you can define an interface that hands it to you in 1024 byte chunks.0 -
I suggest you create your XML (SOAP Envelope including Body contents as a MSXML DomDocument Then use
XMLHTTP.Send(DOMDocument.xml)
to send the request. Alternatively you may just construct the SOAP Body as a DOMDocument and use it likeXMLHTTP.send( '<?xml version="1.0" encoding="UTF-8"?>'+ '<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">' + '<soapenv:Header/>'+ '<soapenv:Body>'+ XMLDocument.xml+ '</soapenv:Body>'+ '</soapenv:Envelope>');
0 -
vaprog wrote:I suggest you create your XML (SOAP Envelope including Body contents as a MSXML DomDocument Then use
XMLHTTP.Send(DOMDocument.xml)
to send the request. Alternatively you may just construct the SOAP Body as a DOMDocument and use it like
Hello vaprog,
I exactly use that manner. But at that point NAV gives string restriction error.
I think it is the most viable solution to create and use automation objects as hjhansen suggests for versions below 2009. For 2009 classic client, I think to consume 3rd party WS in a separate codeunit by using DotNet proxy dll and publish this codeunit as NAV's WS, guaranteeing the function parameter clarity. Because the published codeunit will be run on the server side, using dotNet variables will not be a problem. Then I can consume that NAV's web service within the classic client in a much more simple way.
I hope I am not wrong?Cem Karaer @ Pargesoft
Dynamics NAV Developer since 20050 -
Hello all,
I successfully created a proxy dotNET dll for calling WS as described follows:
http://dynamicsuser.net/blogs/waldo/archive/2011/12/20/net-interop-consume-a-third-party-web-service-check-vat-registration-no.aspx
But one more problem happened when I used dll in C/AL. The reason of the problem is described below:
http://stackoverflow.com/questions/352654/could-not-find-default-endpoint-element
The solution for this problem is to copy and paste the content of the config file of proxy dll into the Microsoft.Dynamics.Nav.Server.exe.config file located under the service folder of NAV. Just copy-pasting the dll and its config file to the Add-ins folder isn't enough because NAV server executable (Microsoft.Dynamics.Nav.Server.exe) looks for necessary endpoint configuration in its configuration file, not dll's.Cem Karaer @ Pargesoft
Dynamics NAV Developer since 20050 -
Hello,
I have one little rough to rasp:
When I use WCF classes as dotNet variables, nullable variables get following form:System.Nullable`1
I figured out no way to assign any value to that kind of class property. How can I set a nullable property of a dotNet variable?Cem Karaer @ Pargesoft
Dynamics NAV Developer since 20050 -
Hello,
As the following entry shows, there is no way to do this
http://mibuso.com/forum/viewtopic.php?f=32&t=58529&hilit=nullableCem Karaer @ Pargesoft
Dynamics NAV Developer since 20050 -
cemkaraer wrote:Hello vaprog,
I exactly use that manner. But at that point NAV gives string restriction error.
Here's how I did it for classic:VAR XMLDocRequest@1100118020 : Automation 'Microsoft XML, v6.0'.DOMDocument60; XMLSOAP : Automation 'Microsoft XML, v6.0'.DOMDocument60; TempBlob : Record 99008535; OutStrm : OutStream; InStrm : InStream; ... EnvelopeSOAPRequest(XMLRequest,XMLSOAP); TempBlob.Blob.CREATEOUTSTREAM(OutStrm); XMLSOAP.save(OutStrm); TempBlob.Blob.CREATEINSTREAM(InStrm); XmlHttp.send(InStrm); CLEAR(OutStrm); CLEAR(InStrm); CLEAR(TempBlob);
PROCEDURE EnvelopeSOAPRequest( VAR Request : Automation 'Microsoft XML, v6.0'.DOMDocument60; VAR SOAP : Automation 'Microsoft XML, v6.0'.DOMDocument60); VAR BodyElement : Automation 'Microsoft XML, v6.0'.IXMLDOMNode; NewNode : Automation 'Microsoft XML, v6.0'.IXMLDOMNode; DocFragment : Automation 'Microsoft XML, v6.0'.IXMLDOMDocumentFragment; BEGIN // places Request DOM in SOAP envelope's Body element // returns resulting DOM in VAR parameter SOAP CLEAR(SOAP); CREATE(SOAP); SOAP.loadXML( '<?xml version="1.0" encoding="UTF-8"?>'+ '<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">' + '<soapenv:Header/>'+ '<soapenv:Body>'+ '</soapenv:Body>'+ '</soapenv:Envelope>'); SOAP.setProperty('SelectionNamespaces','xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"'); BodyElement := SOAP.selectSingleNode('/s:Envelope/s:Body'); NewNode := Request.documentElement; NewNode := SOAP.importNode(NewNode,TRUE); NewNode := BodyNode.appendChild(NewNode); END;
It might be easier to construct the request withing the envelope's body element from the beginning rather than adding the envelope later.
The main part, though, is to use streams instead of strings.0
Categories
- All Categories
- 73 General
- 73 Announcements
- 66.6K Microsoft Dynamics NAV
- 18.7K NAV Three Tier
- 38.4K NAV/Navision Classic Client
- 3.6K Navision Attain
- 2.4K Navision Financials
- 116 Navision DOS
- 851 Navision e-Commerce
- 1K NAV Tips & Tricks
- 772 NAV Dutch speaking only
- 617 NAV Courses, Exams & Certification
- 2K Microsoft Dynamics-Other
- 1.5K Dynamics AX
- 320 Dynamics CRM
- 111 Dynamics GP
- 10 Dynamics SL
- 1.5K Other
- 990 SQL General
- 383 SQL Performance
- 34 SQL Tips & Tricks
- 35 Design Patterns (General & Best Practices)
- 1 Architectural Patterns
- 10 Design Patterns
- 5 Implementation Patterns
- 53 3rd Party Products, Services & Events
- 1.6K General
- 1.1K General Chat
- 1.6K Website
- 83 Testing
- 1.2K Download section
- 23 How Tos section
- 252 Feedback
- 12 NAV TechDays 2013 Sessions
- 13 NAV TechDays 2012 Sessions