Call external web service using new CU 1290

With Nav 2015 there came some new objects. One of them is CU 1290 “Web Service Request Mgt.”.

Here is a short sample, how to use it:

the variables:
Url : Text
reqText : Text
WebServReqMgt : Codeunit : Web Service Request Mgt.
ReqBodyOutStream : OutStream
ReqBodyInStream : InStream
Username : Text
Password : Text
RespBodyInStream : InStream
ResponseXmlDoc : DotNet : System.Xml.XmlDocument.’System.Xml, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089′
TempBlob : Record : TempBlob

the code:
Url := 'http://www.w3schools.com/xml/tempconvert.asmx';
reqText := '' + '10' +
'';

// save request text in instream
TempBlob.”Primary Key” := 1;
TempBlob.Blob.CREATEOUTSTREAM(ReqBodyOutStream);
ReqBodyOutStream.WRITE(reqText);
TempBlob.Blob.CREATEINSTREAM(ReqBodyInStream);

// run the WebServReqMgt functions to send the request
WebServReqMgt.SetGlobals(ReqBodyInStream,Url,Username,Password);
WebServReqMgt.DisableHttpsCheck;
WebServReqMgt.RUN;

// get the response
WebServReqMgt.GetResponseContent(RespBodyInStream);
ResponseXmlDoc := ResponseXmlDoc.XmlDocument;
ResponseXmlDoc.Load(RespBodyInStream);
MESSAGE(ResponseXmlDoc.InnerXml);

As you can see Username and Password are empty. That’s ok, if you run the call within the same AD or like in most cases, the target web service needs no authentication.

Changes in CU 1290
Using Credentials
for the case, you want to use credentials, do the following:
add a new local variable
NetCredential : DotNet : System.Net.NetworkCredential.’System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089′

in fct. BuildWebRequest replace
HttpWebRequest.UseDefaultCredentials := TRUE;
by
IF (GlobalUsername <> '') AND (GlobalPassword <> '') THEN BEGIN
NetCredential := NetCredential.NetworkCredential(GlobalUsername,GlobalPassword);
HttpWebRequest.Credentials := NetCredential;
END ELSE
HttpWebRequest.UseDefaultCredentials := TRUE;

ContentType
in fct. BuildWebRequest replace
HttpWebRequest.ContentType := ContentTypeTxt;
by
HttpWebRequest.ContentType := 'text/xml;charset=utf-8';

ContentTypeTxt has value “multipart/form-data; charset=utf-8”. the web service call won’t work with that content type.

cheers

Advertisements

20 thoughts on “Call external web service using new CU 1290

  1. Hello,

    Thank you for the post. Can you please give us a hint on how to build the “reqText” automatically (C/AL code or .net) ? Maybe how we can do that using the WSDL ?

    Best regards

    Like

  2. Hi Jonathan,

    Thank you for taking time to answer me. The idea to use CU 6224 is the way to go for me (for the tests I’m doing at least). The problem is that I do not know how to build the ReqText as you did.

    Here is the scenario I’m testing ; I created a CU with the following function:

    DoUppercase(InputText : Text) : Text
    EXIT(UPPERCASE(InputText));

    I published the CU as a WS. Then I used the code you provide, I changed the URL and the ReqText as below:

    URL := ‘http://localhost:7047/Cronus906W1/WS/CRONUS%20International%20Ltd.%202/Codeunit/mywebservice’;
    ReqText := ”+’uppercase this for me’+”;

    When I run the CU to consume the ‘mywebservice’, I get this error “The expected data was not received from the web service” (no matter the credentials I use -Default or User/Password-).

    Can you please help me with that? –> I’m using NAV 2016 W1 CU6 by the way.

    P.S: your example works fine with URL = ‘http://www.w3schools.com/xml/tempconvert.asmx’. I believe w3schools updated the link since you wrote this article 🙂

    Like

  3. In fact, I changed this also (The CU 1290 structure has changed):

    //SOAPWebServiceRequestMgt.RUN;
    SOAPWebServiceRequestMgt.SendRequestToWebService;

    The error I get is related to the function “ExtractContentFromResponse” (in CU 1290). This function fails because I get the WSDL structure as a response from “mywebservice”. Now, I’m trying to understand why I get the WSDL for response…

    Like

  4. i developed a simple web service in c#.

     namespace WebServiceNS  
     {  
       [WebService(Namespace = "http://tempuri.org/")]  
       [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]  
       [System.ComponentModel.ToolboxItem(false)]  
       public class WebService1 : System.Web.Services.WebService  
       {  
         [WebMethod]  
         public string GetUpperCase(string lowerCaseText)  
         {  
           if (!string.IsNullOrEmpty(lowerCaseText))  
             return lowerCaseText.ToUpper();  
           return string.Empty;  
         }  
       }  
     }  
    

    then i ran the new webservice with http://localhost:63427/WebService1.asmx?op=GetUpperCase
    in the browser window you can then see the wsdl code:

    POST /WebService1.asmx HTTP/1.1
    Host: localhost
    Content-Type: text/xml; charset=utf-8
    Content-Length: length
    SOAPAction: “http://tempuri.org/GetUpperCase”

     <?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>  
       <GetUpperCase xmlns="http://tempuri.org/">  
        <lowerCaseText>string</lowerCaseText>  
       </GetUpperCase>  
      </soap:Body>  
     </soap:Envelope>  
    

    to call the web service with c/al and set the correct value for reqText, simply copy the lines between the soap:Body tag.
    so the value for reqText in that case is:

     reqText := '<GetUpperCase xmlns="http://tempuri.org/"><lowerCaseText>hello</lowerCaseText></GetUpperCase>';  
    

    GetUpperCase is the webmethod name , tag property xmlns is set with the namespace defined as attribute in the c# webmethod. lowercasetext is the name of the parameter. so it’s quite simple to use.

    the result, when calling that web service:

     <GetUpperCaseResponse xmlns="http://tempuri.org/"><GetUpperCaseResult>HELLO</GetUpperCaseResult></GetUpperCaseResponse>  
    

    you can see: hello is converted to HELLO.. 😉

    cheers

    Like

  5. Hi Jonathan, I am getting a fallowing error when i run same code . If possible please let me know how to resolve this error.

    Microsoft Dynamics NAV
    —————————

    A call to System.Xml.XmlDocument.Load failed with this message: Root element is missing.
    —————————
    OK
    —————————

    Like

  6. HI Moxie, I got another response after few changes to service

    Microsoft Dynamics NAV
    —————————

    A call to System.Net.HttpWebRequest.GetResponse failed with this message: The remote server returned an error: (500) Internal Server Error.
    —————————
    OK
    —————————

    Like

      1. Hi,
        I have the same problem, Root is missing. I use the same code like you post. Can i send my code too to your mail? Thanks

        Like

    1. hi, this can be tricky, because the created soap structure is a bit different compared with that one of standard .net web services. why do you need that? data exchange between nav systems can be made easier. please describe your scenario. regards

      Like

    1. Hi Jonathan,
      Thanks for your fast response. But i still get the same error. Note : i’m using NAV 2016 CU 12. Thanks

      Url := ‘http://www.w3schools.com/xml/tempconvert.asmx’;

      reqText := ” +
      ‘string’ +
      ”;

      // save request text in instream
      TempBlob.”Primary Key” := 1;
      TempBlob.Blob.CREATEOUTSTREAM(ReqBodyOutStream);
      ReqBodyOutStream.WRITE(reqText);
      TempBlob.Blob.CREATEINSTREAM(ReqBodyInStream);

      // run the WebServReqMgt functions to send the request
      WebServReqMgt.SetGlobals(ReqBodyInStream,Url,Username,Password);
      WebServReqMgt.DisableHttpsCheck;
      WebServReqMgt.RUN;

      // get the response
      WebServReqMgt.GetResponseContent(RespBodyInStream);
      ResponseXmlDoc := ResponseXmlDoc.XmlDocument;
      ResponseXmlDoc.Load(RespBodyInStream);
      MESSAGE(ResponseXmlDoc.InnerXml);

      Like

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s