I am currently involved in a project where I need to integrate Dynamics AX with a 3rd party payroll system. Dynamics AX 2012 provides a rich integration framework called Application Integration Framework or (AIF). One of the core strengths of this framework is the ability to generate a typed schema through a configuration wizard. Combine that with a AX’s ability to create inbound and outbound ports and you now have the ability to generate export(and import if interested) files rather quickly.
When I mentioned in the previous paragraph “typed messages” I meant that AX will generate XSD schemas that we can include in our BizTalk projects. This is a breath of fresh air compared to some other ERP systems where you get handed a CSV flat file that you have to build a flat file schema for.
In my scenario I was receiving a list of Work Orders so a colleague working on the AX side was able to provide me with the Work Order Schema and an imported schema that includes AX types. At this point I add the schemas into my solution, build my map and wire everything up. Go to run an initial test and was presented with the following error:
Details:The published message could not be routed because no subscribers were found. This error occurs if the subscribing orchestration or send port has not been enlisted, or if some of the message properties necessary for subscription evaluation have not been promoted.
This is a pretty standard error message that basically comes down to BizTalk received a message that it was not expecting. The reason why BizTalk was not expecting it was because AX wraps outbound messages with a SOAP Envelope as you can see in the image below.
SOAP Envelopes are certainly nothing new but I didn’t expect AX to use them when writing a file to the file system. When receiving Web/WCF Services BizTalk automatically takes care of extracting the message body from the incoming SOAP message for us. With the FILE Adapter that facility just does not exist.
You will notice in screenshot below that there is a namespace that is specific to AX. This got me thinking that AX probably has an XSD for this message type as well.
After digging around a bit I did find the location of the AX schemas to be in the Program files\Microsoft Dynamics AX\60\Server\MicrosoftDynamicsAX\bin\Application\Share\Include folder. The schema that I was looking for was called Message.xsd
Just adding this the BizTalk project was not enough. I needed to make a few small tweaks to the schema:
- Click the “Schema Icon” of the schema and then set the Envelope property to be True. This instructs BizTalk that it is an envelope schema and when BizTalk sees this message that it needs to strip out the Envelope which in this case is a SOAP Envelope.
- Set the Body XPath property by selecting the Root Node of the schema and then populating the appropriate value which in this case is
/*[local-name()='Envelope' and namespace-uri()='http://schemas.microsoft.com/dynamics/2011/01/documents/Message']/*[local-name()='Body' and namespace-uri()='http://schemas.microsoft.com/dynamics/2011/01/documents/Message']/*[local-name()='MessageParts' and namespace-uri()='http://schemas.microsoft.com/dynamics/2011/01/documents/Message']
We can now deploy our application. When it comes to our Receive Location that will be picking up this message, we want to ensure that we are using the XMLReceive Pipeline. Within this Pipeline the XML Disassembler stage will take care of the SOAP envelope so that when the message body is presented to the MessageBox that any subscribers will receive the expected message body.
When I first discovered that I was receiving a SOAP wrapped message my instincts said maybe AX could just use a WCF port instead of a FILE port. This just wasn’t the case, there are only two options when it comes to configuring an outbound port: FILE and MSMQ. Using MSMQ would not of helped me in this case as the same issue would have existed.
AX certainly does provide the ability to call a WCF service but it is a more custom based approach. I would have had to expose this schema as a WCF service but then my AX colleagues would have had to write code against the proxy to populate all of the different data elements. This would have defeated the purpose of using the AIF framework in order to expedite the ability to delver a solution under very tight timelines. Luckily with a little tinkering we were able to come up with a reasonable solution without writing custom code.
I have to think that AX is wrapping these messages in a SOAP Envelope for a reason. Perhaps a WCF outbound port is coming in an upcoming release?