Tuesday, June 29, 2010

AX .NET Business Connector – How to Open Multiple Company Connections Simultaneously

As part of a recent project we needed to access the .NET Business Connector in Dynamics AX through a component (in this case for data lookup in BizTalk’s Business Rule Engine).  Because we were going to have many messages flowing through in a short period of time all requiring evaluation of business rules based on AX data, we intended to create some helper classes to enable the reuse of AX connections and to cache data used in the rules.  Our challenge was that messages were destined for different companies in AX.  If you have two orchestrations simultaneously evaluating these rules which in turn simultaneously open connections to AX you run into a bit of trouble.

Suppose you have two Microsoft.Dynamics.BusinessConnectorNet.Axapta objects (DAX1, DAX2), one each for different companies:

System.Net.NetworkCredential credential = new System.Net.NetworkCredential("<BC_USER>", "<BC_PASSWORD>", "<BC_DOMAIN>");
DAX1.LogonAs("<AX_USER>”, "<BC_DOMAIN>", credential, "<COMPANY_1>", "", "<COMPANY_1>@<AOS>:<PORT>", "");
DAX2.LogonAs("<AX_USER>”, "<BC_DOMAIN>", credential, "<COMPANY_2>", "", "<COMPANY_2>@<AOS>:<PORT>", "");

When you reach the second LogonAs statement, the logon fails with an exception of type LogonSystemChangedException.  ("The logon failed because the logon parameters do not match those currently being used in Business Connector").

The following blog post gives a good description of the Business Connector’s intended use, which is essentially to act as a client:

http://blogs.msdn.com/floditt/archive/2008/07/24/the-net-business-connector-bc-net-and-the-iis.aspx

At first it seemed there was no way to do this.  We opened a ticket with Microsoft and as a short term solution, installed the AX Client on the BizTalk server so that we could use the overload of LogonAs that takes a path to an .axc file with connection details.  It turns out this works, however you have the overhead of installing the AX client on the BizTalk server and creating .axc files for BizTalk.  We didn’t like this idea also because of issues with maintaining the .axc files and the slower performance of the Business Connector using the Client to read the .axc file.

Ultimately Microsoft came back with a resolution.  It turns out that the parameter for the object server (second last parameter) was incorrect.  Unfortunately in many code samples and on MSDN, this parameter is defined as "Company1@AosInstance:PortNumber”.  The first part of this should actually be the Instance Name (by default “DynamicsAx”) and the part after the @ sign is the Server name.  A better example might be “DynamicsAx@AOSSERVER01:2712”.

Changing the above code to use Instance names works:

System.Net.NetworkCredential credential = new System.Net.NetworkCredential("<BC_USER>", "<BC_PASSWORD>", "<BC_DOMAIN>");
DAX1.LogonAs("<AX_USER>”, "<BC_DOMAIN>", credential, "<COMPANY_1>", "", "<INSTANCE_NAME>@<AOS>:<PORT>", "");
DAX2.LogonAs("<AX_USER>”, "<BC_DOMAIN>", credential, "<COMPANY_2>", "", "<INSTANCE_NAME>@<AOS>:<PORT>", "");

So now we can open two connections to AX simultaneously with different companies in the same object instance.

No comments: