Tuesday 2 August 2022

Consuming WCF-Custom BizTalk Service From Dynamic NAV

 

Objective

The client want Dynamic NAV able to send XML EDI to BizTalk Server. The BizTalk server and NAV services are hosted within the same domain network. Using secure connection is optional and NTLM is sufficient enough.

Design & Planning

They are few option of COM component or .NET assembly that can be used at NAV to connecting to BizTalk Server. In here, I am using Windows HTTP Service  which is presently available in Windows Server it seft. This component is compatible with NAV classic like NAV 2009R2 or the .NET assembly version for higher NAV like NAV2013R2 and above.

At BizTalk Server, I decided to use WCF-Custom adapter. This adapter is in-process managed by BizTalk host process and ability to configured to match the Windows HTTP Service component. The WCF providing connection via HTTP protocols and the message defaulted wrap in SOAP format. Considering that windows HTTP service component are not providing the SOAP format capabilities. Therefore I would need to use plain old XML messaging style that not require any format but the XML message itself.

Publishing WCF-Custom Service

I am started with publishing a new one way received port and a new WCF-Custom received location. The address URL should be follow the FQDN of the localhost and I am using port 8080. This port number must be unused port no by localhost and the path can be given any name that is unique and easy to remember.


In binding tab screen, I had custom binding as my preference. I had decided to use HTTP transport and NTLM authentication. I don't need secure connection because NAV and BizTalk within the organization. Certain the transport and security mode selection must in line with the capabilities of windows HTTP service component and NAV.



One important binding property to set is the message version. This property is determine the message format that BizTalk WCF service will use for publishing the web service. The default value would be message version SOAP 1.2. This message version require the client side to encapsulate the request XML message in SOAP format structure version 1.2. I set to "None" message version property to indicate SOAP format is not required.



On the behavior tab, we need to enable our web service metadata true GET method. This is important so that BizTalk WCF providing WSDL information that is useful for me to understand how to consume the web service. This properties is can be disabled once the two system already run in live environment.



In the messages tab, the inbound BizTalk message body option is not relevant anymore. This is because the message format is not using SOAP format. The important section is the error handling where I would like to suspend request message upon failure and include exception detail in fault. The last check box actually is not necessary needed. This is because the exception detail will be push back to the client side and within NAV need to handle the WCF fault error message format. 



Publishing web service with WCF-Custom adapter does not require any service contract. This approach has advantages for system the integration within organization that require multiple type of transaction process to integrate with. I could have one publishing web service as general receiving location to accept any incoming transaction message and with BizTalk routing engine it will relay the messages to the right subscriber (i.e orchestration or send port).

Once the transport properties setup is done, I will able to see the WSDL of my published web service. Following picture show the WSDL content to further detail understanding. Kindly notice that BizTalk generate one operation name called "BizTalkSubmit" where it describe nothing for an input and output section. With this definition, the web service not require any message format and not bond to certain message type or contract.



NAV Consume BizTalk WCF Service

Move on to NAV client side, I would like to create a simple code unit that connect and send XML over to BizTalk web service above. In this new code unit I am declaring a new global automation variable with sub type of "WinHttpRequest" under Microsoft WinHTTP Services COM. Following picture how its been declared in the code unit.


Following picture of code show how to consume WCF BizTalk published web service from NAV client side. The code is basically simply sending a XML file and show the send status and response if any. The COM component will generate the status and status text after calling the "send" method. The status would be like standard HTTP protocols status code where the status code 200 "OK" means successfully send the message to BizTalk Server. Meanwhile, the failed sent is when COM component generate other than code 200. 



Detail About Status Code

Windows HTTP service received any status code for any connection result. For the status code 200 means BizTalk Server received the XML message and store it in messagebox database. However, the new message is not yet identified and further processed by BizTalk Server. This is a norm behavior for one way BizTalk received location in publishing the BizTalk WCF web service. 

With two ways communication BizTalk received location, the status code 200 "OK" only return when BizTalk server response with the response message. In this case the "send" method will hold a while to receive acknowledgement or negative acknowledgement from  BizTalk server. The "ResponseStream" method will contain the response message or the error detail message. The justification for the two ways communication is not necessary under my requirement. 

Error Connection

I have record down some common exception error behavior during the testing. Error status code 404 "Not Found" is return to the client for two possibly reason. Firstly, The BizTalk WCF received location is down. Secondly, the URL or the path is ot found incorrect. Interestingly, the response stream contain the HTML error page like following picture.



I had encounter error status code 413 "Request Entity too Large". This was happened when I sent a XML message larger than 64KB. Typically, I don't have XML larger than this limit, however I could increase this limit in the BizTalk WCF receive location transport property. Under binding pane of HTTP transport sub tree, there is a property that define the maximum size for receive message. Following picture show the property location.

 


Other than above error, there are few reason the component throw run time exception when call to member send failed. I have noted down the reason like localhost unable to resolve the host name of the URL, incorrect port number is used or windows firewall is blocking the communication. The codes connection logic object separation is required to handle this situation so that system able to flag the error send and gracefully end the process.    

Summary

The full solution at BizTalk Server  require deployment of Schema and orchestration to handle the XML message but that is not within this context. This approach solution still valid with Dynamics NAV 2018 and perhaps BC. In NAV 2018, there is standard codeunit “Http Web Request Mgt.” (1297) which similar abilities for consuming BizTalk Server WCF service.