Microsoft Dynamics NAV: Send XML Document via HTTP Post

I had previously discussed exporting an XMLPort to a file, web service and as BigText.  There may also be a need to exchange XML data via HTTP Post.  I will build on the XMLPort to BigText example.

 
CLEAR(TempBlob);
TempBlob.Blob.CREATEOUTSTREAM(OS);
Customer.GET('30000');

//Set the view for the XMLPort
 CustomerXML.SETTABLEVIEW(Customer);
 
// Use the TempBlob record to get a blob stream
TempBlob.Blob.CREATEOUTSTREAM(OS);
CustomerXML.SETDESTINATION(OS);
// export the contents of the XMLPort to a blob
CustomerXML.EXPORT;
 
TempBlob.CALCFIELDS(Blob);
TempBlob.Blob.CREATEINSTREAM(IS);


IF ISCLEAR(XMLHTTP) THEN //'Microsoft XML, v6.0'.XMLHTTP60
  CREATE(XMLHTTP);
IF ISCLEAR(XMLDoc) THEN //'Microsoft XML, v6.0'.DOMDocument
  CREATE(XMLDoc);

XMLDoc.load(IS);

XMLHTTP.open('POST', WebAddress, FALSE);
XMLHTTP.setRequestHeader('Content-Type', 'text/xml');
XMLHTTP.send(XMLDoc);

IF XMLHTTP.status = 200 THEN BEGIN
  IF (XMLHTTP.responseText <> '') THEN BEGIN

  END;
END ELSE BEGIN
  ERROR('Status %1 %2',XMLHTTP.status,XMLHTTP.statusText);
END;

CLEAR(XMLDoc);
CLEAR(XMLHTTP);

 

The variables are declared as:

 

Microsoft Dynamics Nav: XMLPort through BigText

With the addition of Web Services, exchanging data and processing code with Microsoft Dynamics NAV from an external source became a relatively simple task.  By exposing an XMLPort, working with class object and binding to the underlying data allows for an easy way to exchange data with Microsoft Dynamics NAV.  If the requirement is to pass the text (string) output of the XMLPort as text you can pass it through as a BigText variable. 

// Get Recordset
Customer.GET('30000');

//Set the view for the XMLPort
CustomerXML.SETTABLEVIEW(Customer);

// Use the TempBlob record to get a blob stream
TempBlob.Blob.CREATEOUTSTREAM(OS);
CustomerXML.SETDESTINATION(OS);
// export the contents of the XMLPort to a blob
CustomerXML.EXPORT;

TempBlob.CALCFIELDS(Blob);
TempBlob.Blob.CREATEINSTREAM(IS);
// Read the blob contents to the big text
Response.READ(IS);

 

Screenshot of XMLPort to BigText Microsoft Dynamics NAV

The variables are declared as follows:

Microsoft Dynamics NAV variables for sample code

Microsoft Dynamics NAV: Application Server from the Command Line

The NAV Application Server is (NAS) is a middle-tier server that executes NAV business logic (code) without user intervention. The NAS operates as an unattended client that is connected to the database server and runs as a service on a computer.   One benefit of the NAS is that if it loses communication with the database server due to connection or server issues it does not stop, instead it will continue to attempt a connection to the database server.
When you install a NAS the setup will prompt you for the parameter information to use for connecting and communicating with the database server. This makes for an easy installation; however you may need to run more than one NAS on a computer. In this case you will need to install the NAS from the command line.
In the Application Server directory there are two executable files for launching the NAS; nas.exe and nassql.exe. To install the application server you can enter the following at the command line (example is for SQL Server) and substituting your values where appropriate:
nassql appservername=<appserver service name>, servername=<SQL Server/instance>,database=<database name>,Company="<Company Name>",startupparameter=<parameter to pass>,installasservice
To uninstall as NAS from the command line enter the following command:
nassql uninstallasservice, appservername=<appserver service name>
 

Exception message: A potentially dangerous Request.Form value was detected from the client

A recent requirement was to transfer XML documents via HTTP Post on the dotNET 2.0 platform. I had set up the “application” to receive the XML stream and save the data as a file (Sample codes demonstrates reading location from config and saving the stream; content validation not shown).
protected void Page_Load(object sender, EventArgs e)
        {
            using (System.IO.StreamReader reader = new System.IO.StreamReader(Request.InputStream))
            {
                String xmldata = reader.ReadToEnd();
                Response.ContentType = "text/xml";
                //Response.Write(xmldata);
                Response.Write(String.Format("Bytes received: {0}", xmldata.Length));

                string myConfigValue = WebConfigurationManager.AppSettings["DropOffFolder"];
                if (System.IO.Directory.Exists(myConfigValue))
                {
                    Guid g = new Guid();
                    g = Guid.NewGuid();
                    string filename = myConfigValue + g.ToString() + ".xml";
                    //Response.Write(filename);
                    using (StreamWriter sw = new StreamWriter(filename))
                    { sw.Write(xmldata); }
                }

                Response.ContentEncoding = System.Text.Encoding.UTF8;
                Response.Flush();
                Response.End();
                Response.Close();
            }
        }
 
During testing I had sent successfully exchanged text data. However, when I tried to send XML data I received a 500 response error from the server, which is very generic.  I reviewed the event log on the server to see if IIS logged any messages and noticed the following warning:
Exception information:
    Exception type: HttpRequestValidationException
    Exception message: A potentially dangerous Request.Form value was detected from the client.

 

The server was validating the data stream, which is uuencoded HTML. To bypass this particular validation I added  ValidateRequest="false to the page directive. The ValidateRequest attribute checks for potentially dangerous input data that could compromise the security of your application or a scripting attack.

 

Note:  When ValidateRequest is disabled, content can be submitted to your application; it is the responsibility of the application developer to ensure that content is properly encoded or processed.

Another way to process the data, without having to disable validation, would be to encode and decode it using Server.HtmlEncode(string) and Server.HtmlDecode(string).

Microsoft Dynamics Nav: Web Services User Credentials

In previous posts (Adding a Record through Web Services, Retrieving a set of Records through Web Services, Using an XMLPort as a .NET DataSource) I demonstrated a simple solution for connecting to a Microsoft Dynamics Nav Web Service. In each of the examples the default user credentials were used. To connect to a Microsoft Dynamics Nav Web Service with specified user credentials you use the System.Net.NetworkCredential:
 
            ws = new GetSetCustomers_Binding();
            
            //ws.UseDefaultCredentials = true;
            System.Net.NetworkCredential cred = new System.Net.NetworkCredential("username","password","domain");
            ws.UseDefaultCredentials = false;
            ws.Credentials = cred;
 

Reading Stuff

Information in this document subject to change without notice.
All Software source code published is for demonstration and knowledge sharing purposes only. The Code is supplied "as is" without warranty as to result, performance or merchantability. Use at your own risk.
The opinions expressed herein are the opinions of the author and do not reflect those of any other entity.