Options

NAV2013 Web Service call from JavaScript

GreatScott000GreatScott000 Member Posts: 40
edited 2015-03-31 in NAV Three Tier
I have used Freddy's logic http://blogs.msdn.com/b/freddyk/archive/2010/01/21/connecting-to-nav-web-services-from-javascript.aspx?CommentPosted=true#commentmessage to start with but the problem I get is that the responseXML is "undefined" but the responseText has (most of) what I need. Any ideas on how to get the responseXML?

This is the code.
<!DOCTYPE html>
<html>
<head>
    <title></title>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <script type="text/javascript">

        var baseURL = 'http://localhost:7047/DynamicsNAV70/WS/';
        var cur;
        var SystemServiceURL = baseURL + 'SystemService';
        var VendorPageURL;

        var SoapEnvelopeNS = 'http://schemas.xmlsoap.org/soap/envelope/';
        var SystemServiceNS = 'urn:microsoft-dynamics-schemas/nav/system/';
        var VendorPageNS = 'urn:microsoft-dynamics-schemas/page/vendor';

        <!-- Function to Invoke a NAV WebService and return data from a specific Tag in the responseXML  -->
        function InvokeNavWS(URL, method, nameSpace, returnTag, parameters) {
            var result = null;
            try {
                var xmlhttp;
                if (window.XMLHttpRequest) {// code for IE7+, Firefox, Chrome, Opera, Safari 
                    xmlhttp = new XMLHttpRequest();
                }
                else {// code for IE6, IE5 
                    xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
                }

                var request = '<Soap:Envelope xmlns:Soap="' + SoapEnvelopeNS + '">' +
                              '<Soap:Body>' +
                              '<' + method + ' xmlns="' + nameSpace + '">' +
                              parameters +
                              '</' + method + '>' +
                              '</Soap:Body>' +
                              '</Soap:Envelope>';

                // Use Post and non-async 
                xmlhttp.open('POST', URL, false);
                xmlhttp.setRequestHeader('Content-type', 'text/xml; charset=utf-8');
                xmlhttp.setRequestHeader('Content-length', request.length);
                xmlhttp.setRequestHeader('SOAPAction', method);

                // Setup event handler when readystate changes 
                xmlhttp.onreadystatechange = function () {
                    document.writeln("ReadyState - ", xmlhttp.readyState, "<br/>");
                    if (xmlhttp.readyState == 4) {
                        if (xmlhttp.status == 200) {
document.writeln("Got response 200", "<br/>");
document.writeln("ResponseXML:", xmlhttp.responseXML.xml, "<br/>");
document.writeln("ResponseText:", xmlhttp.responseText, "<br/>");
                            xmldoc = xmlhttp.responseXML;
                            xmldoc.setProperty('SelectionLanguage', 'XPath');
                            xmldoc.setProperty('SelectionNamespaces', 'xmlns:tns="' + nameSpace + '"');
                            result = xmldoc.selectNodes('//tns:' + returnTag);
                        }
                    }
                }

                // Send request will return when event has fired with readyState 4 
                xmlhttp.send(request);
            }
            catch (e) {
document.writeln("Got error");
                document.writeln(e.toString());
            }
            return result;
        }

        // Get the Company list 
        function SystemService_Companies() {
            return InvokeNavWS(SystemServiceURL, 'Companies', SystemServiceNS, 'return_value', '');
        }

        function VendorPage_Read(no) {
            return InvokeNavWS(VendorPageURL, 'Read', VendorPageNS, 'Vendor',
                               '<No>' + no + '</No>');
        }

        function VendorPage_ReadMultiple(filters) {
            return InvokeNavWS(VendorPageURL, 'ReadMultiple', VendorPageNS, 'Vendor', filters);
        }

    </script>
</head>
<body>
	<span>Hello World!</span><br/>
    <script type="text/javascript">

        var companies = SystemService_Companies();
        document.writeln('Companies:<br>');
        if (companies == null) {
            document.writeln('Error <br>');
        }
        else {
            document.writeln('Companies:<br>');
            for (var i = 0; i < companies.length; i++) {
                document.writeln(companies[i].text + '<br>');
            }
            cur = companies[0].text;
        }

        if (cur != null) {
            VendorPageURL = baseURL + encodeURIComponent(cur) + '/Page/DSIVendor';
            document.writeln('<br>URL of Vendor Page: ' + VendorPageURL + '<br>');

            var VendorABC = VendorPage_Read('ABC');
            document.writeln('<br>Name of Vendor ABC: ' +
                             VendorABC[0].childNodes[2].firstChild.nodeValue + '<br>');

            document.writeln('<br>Vendors (filtered):<br>');
            var Vendors = VendorPage_ReadMultiple(
                            '<filter><Field>Country_Region_Code</Field><Criteria>US</Criteria></filter>'
                            //+ '<filter><Field>Location_Code</Field><Criteria>RED|BLUE</Criteria></filter>'
                            );
            for (i = 0; i < Vendors.length; i++)
                document.writeln(Vendors[i].childNodes[2].firstChild.nodeValue + '<br>');
        }
        else {
            document.writeln('no current company<br>');
        }

        document.writeln('<br>THE END');

    </script>
</body>
</html>

and this is the output:
Hello World!
ReadyState - 4
 Got response 200
 ResponseXML:undefined
 ResponseText:Company ACompany BCompany C
 Companies:
 Error 
 no current company

THE END

Comments

  • Options
    GreatScott000GreatScott000 Member Posts: 40
    So this has something to do with the difference in XmlHTTPRequest.ResponseXML in IE10 versus IE9. In IE9 it is an MSXML document in IE10 it is a "native" document, whatever that means. Any ideas?
  • Options
    GreatScott000GreatScott000 Member Posts: 40
    So this has something to do with the difference in XmlHTTPRequest.ResponseXML in IE10 versus IE9. In IE9 it is an MSXML document in IE10 it is a "native" document, whatever that means. Any ideas how I can make this work in IE10 without using compatibility mode?
  • Options
    GreatScott000GreatScott000 Member Posts: 40
    So I found a couple of answers to this.
    You can add this to the code to make it return the IE9 type of document in the response where you set the request header values
    try { xmlhttp.responseType = 'msxml-document'; } catch (e) { }
    

    The other key, to resolve the Parameter ??? is null error, you MUST make sure all your the case of the URN and SOAPAction are correct. They are case sensitive. Mismatched case will cause this error:
    Server instance: DynamicsNAV70
    Session type: UnknownClient
    Session ID: N/A
    User: 
    Type: Microsoft.Dynamics.Nav.Service.WebMetadata.ServiceBrokerException
    Message: Parameter XXXX in method WSMETHOD in service WEBSERVICE is null! 
    StackTrace:
         at Microsoft.Dynamics.Nav.Service.WebServices.ServiceCodeunitXmlAdapter.BuildStackFrame(MethodInfo method, XmlElement input)
         at Microsoft.Dynamics.Nav.Service.WebServices.ServiceCodeunitXmlAdapter.<>c__DisplayClass4.<Dispatch>b__0()
         at Microsoft.Dynamics.Nav.Service.WebServices.Disposer.Scope(Code code)
    

    The complete solution for JavaScript is below. It is pretty much the same from Freddy's Bloghttp://blogs.msdn.com/b/freddyk/archive/2010/01/21/connecting-to-nav-web-services-from-javascript.aspx but I have functionalized it a bit more.
    <!DOCTYPE html>
    <html>
    <head>
        <title>Web Service Test</title>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
        <script type="text/javascript">
            var soapEnvelopeNS = 'http://schemas.xmlsoap.org/soap/envelope/';
            var xmlhttp;
            //Function to Invoke a NAV WebService and return data from a specific Tag in the responseXML 
            function InvokeNavWS(URL, method, nameSpace, returnTag, parameters) {
                var result = null;
                try {
                    if (window.XMLHttpRequest) {// code for IE7+, Firefox, Chrome, Opera, Safari 
                        xmlhttp = new XMLHttpRequest();
                    }
                    else {// code for IE6, IE5 
                        xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
                    }
    
                    var request = '<soap:Envelope xmlns:soap="' + soapEnvelopeNS + '">' +
                                  '<soap:Header></soap:Header>' + 
                                  '<soap:Body>' +
                                  '<' + method + ' xmlns="' + nameSpace + '">' +
                                  parameters +
                                  '</' + method + '>' +
                                  '</soap:Body>' +
                                  '</soap:Envelope>';
                    var requestText = request;
                    document.writeln("Request ", requestText
                            .replace(/&/g, '&')
                            .replace(/"/g, '"')
                            .replace(/</g, '<')
                            .replace(/>/g, '>'), "<br/><br/>");
    
                    // Use Post and non-async 
                    xmlhttp.open('POST', URL, false);
                    xmlhttp.setRequestHeader('Content-type', 'text/xml; charset=utf-16');
                    xmlhttp.setRequestHeader('Content-length', request.length);
                    xmlhttp.setRequestHeader('SOAPAction', method);
                    try { xmlhttp.responseType = 'msxml-document'; } catch (e) { }
    
                    // Setup event handler when readystate changes 
                    xmlhttp.onreadystatechange = function () {
                        document.writeln("ReadyState ", xmlhttp.readyState, "<br/>");
                        document.writeln("Status ", xmlhttp.status, "<br/>");
                        document.writeln("Response ", xmlhttp.responseText
                            .replace(/&/g, '&')
                            .replace(/"/g, '"')
                            .replace(/</g, '<')
                            .replace(/>/g, '>'), "<br/><br/>");
    
                        if (xmlhttp.readyState == 4) {
                            if (xmlhttp.status == 200) {
                                xmldoc = xmlhttp.responseXML;
                                xmldoc.setProperty('SelectionLanguage', 'XPath');
                                xmldoc.setProperty('SelectionNamespaces', 'xmlns:tns="' + nameSpace + '"');
                                result = xmldoc.selectNodes('//tns:' + returnTag);
                            }
                        }
                    }
    
                    // Send request will return when event has fired with readyState 4 
                    xmlhttp.send(request);
                }
                catch (e) {
                    document.writeln('<span style="color:red">"', 'Request ', '<br/>',  requestText
                            .replace(/&/g, '&')
                            .replace(/"/g, '"')
                            .replace(/</g, '<')
                            .replace(/>/g, '>'), "<br/><br/>", '</span>');
                    document.writeln('<span style="color:red">"', 'InvokeNavWS ', '<br/>', e.message, '</span>');
                }
                return result;
            }
        </script>
        <script type="text/javascript">
            function CheckArray(array) {
                if (array.constructor.toString().indexOf("Array") > -1) {
                    return true;
                }
                throw "Not an array";
            }
        </script>
        <script type="text/javascript">
            function MakeParamString(paramArray) {
                CheckArray(paramArray);
                var paramString = '';
                for (var i = 0; i < paramArray.length; i++) {
                    paramString += paramArray[i];
                }
                return paramString;
            }
        </script>
        <script type="text/javascript">
            function MakeTag(tagName, value) {
                return "<" + tagName + ">" + value + "</" + tagName + ">";
            }
        </script>
        <script type="text/javascript">
            function serviceUrl() {
                return baseURL + currentCompany + slash() + serviceName;
            }
        </script>
        <script type="text/javascript">
            var baseURL;
            function SetBaseURL(url) {
                //http://server:port/service/WS/';
                if (url == null) {
                    baseURL = 'http://localhost:7047/DynamicsNAV70/WS/';
                }
                else {
                    baseURL = url;
                }
                if (baseURL.substring(baseURL.length - 1, 1) != slash()) {
                    baseURL += slash();
                }
            }
        </script>
        <script type="text/javascript">
            var currentCompany;
            function SetCurrentCompany(companyName) {
                currentCompany = encodeURIComponent(companyName);
            }
        </script>
        <script type="text/javascript">
            var serviceName;
            function SetServiceName(name) {
                if (name == null) {
                    serviceName = "Codeunit/WSInterface"; //case matters
                }
                else {
                    serviceName = name;
                }
            }
        </script>
        <script type="text/javascript">
            var serviceNameSpace;
            function SetServiceNameSpace(nameSpace) {
                if (nameSpace == null) {
                    serviceNameSpace = 'urn:microsoft-dynamics-schemas/codeunit/WSInterface';  //Note, no trailing slash
                }
                else {
                    serviceNameSpace = nameSpace;
                }
            }
        </script>
        <script type="text/javascript">
            function slash() {
                return "/";
            }
        </script>
        <script type="text/javascript">
            function TransferOrderCreate(pUser, pFromLocation, pToLocaton, oOrderNo, oStatusText) {
                return InvokeNavWS(serviceUrl(), 'TransferOrderCreate', serviceNameSpace, 'return_value'
                    , MakeParamString([
                        MakeTag("pUser", pUser)
                        , MakeTag("pFromLocation", pFromLocation)
                        , MakeTag("pToLocation", pToLocaton)
                        , MakeTag("oTransferOrderNo", oOrderNo)
                        , MakeTag("oStatusText", oStatusText)
                    ]));
            }
        </script>
        <script type="text/javascript">
            function TestNoParam() {
                return InvokeNavWS(serviceUrl(), 'TestNoParam', serviceNameSpace, 'return_value'
                    , ""
                    );
            }
        </script>
        <script type="text/javascript">
            function Test1Param(Param1) {
                return InvokeNavWS(serviceUrl(), 'Test1Param', serviceNameSpace, 'return_value'
                    , MakeParamString([
                      MakeTag("Param1", Param1)]));
            }
        </script>
        <script type="text/javascript">
            function Test1In1Out(param1, outParam) {
                return InvokeNavWS(serviceUrl(), 'Test1In1Out', serviceNameSpace, 'return_value'
                    , MakeParamString([MakeTag("param1", param1), MakeTag("outParam", outParam)]));
            }
        </script>
    
    
        <script type="text/javascript">
            SetBaseURL('http://localhost:7047/DynamicsNAV70/WS');
            SetCurrentCompany("CRONUS USA, INC.");
            SetServiceName();
            SetServiceNameSpace();
        </script>
    
    </head>
    <body>
        <span>Hello World!</span><br />
        <script type="text/javascript">
            document.writeln(baseURL, "<br/>");
            document.writeln(currentCompany, "<br/>");
            document.writeln(serviceName, "<br/>");
            document.writeln(serviceNameSpace, "<br/>");
            document.writeln("<br/>");
        </script>
        <script>
            //var result = TestNoParam(); 
            //var result = Test1Param("USER"); 
            //var result = Test1In1Out("MyParam", "");
            var result = TransferOrderCreate("USER", "BIN1", "BIN2", "", "");
            document.write("Result <strong>", result, "</strong>");
        </script>
    </body>
    </html>
    
  • Options
    mdPartnerNLmdPartnerNL Member Posts: 802
    thx for sharing :thumbsup:
Sign In or Register to comment.