Ringer AIF Document Services direkt från X++ i Dynamics AX 2012
Publicerad: 16 februari 2025 kl. 11:23:16 UTC
I den här artikeln förklarar jag hur man anropar Application Integration Framework-dokumenttjänster i Dynamics AX 2012 direkt från X++-kod, som emulerar både inkommande och utgående samtal, vilket kan göra det betydligt lättare att hitta och felsöka fel i AIF-kod.
Calling AIF Document Services Directly from X++ in Dynamics AX 2012
Informationen i det här inlägget är baserad på Dynamics AX 2012 R3. Det kan eller kanske inte är giltigt för andra versioner.
Jag hjälpte nyligen en kund att implementera en inkommande port för Application Integration Framework (AIF) för att skapa kunder baserat på data som de fick från ett annat system. Eftersom Dynamics AX redan tillhandahåller dokumenttjänsten CustomCustomer, som implementerar logiken för detta, bestämde vi oss för att hålla det enkelt och använda standardlösningen.
Det visade sig dock snart att det fanns en hel del problem att få det externa systemet att generera XML som Dynamics AX skulle acceptera. XML-schemat som genereras av Dynamics AX är ganska komplext och det verkar också finnas få buggar i Dynamics AX som ibland gör att det avvisar XML som är schemagiltigt enligt andra verktyg, så allt som allt visade det sig vara mindre enkelt än jag hade trott.
Under strävan kämpade jag ofta för att komma på exakt vad problemet var med vissa XML-filer eftersom felmeddelandena från AIF är mindre informativa. Det var också tråkigt, eftersom jag var tvungen att vänta på att det externa systemet skulle skicka ett nytt meddelande över MSMQ och sedan igen för att AIF skulle hämta meddelandet och bearbeta det innan jag kunde se ett fel.
Jag undersökte därför om det är möjligt att anropa servicekoden direkt med en lokal XML-fil för något snabbare testning och det visar sig att det är det – och inte bara det, det är väldigt enkelt att göra och ger faktiskt mycket mer meningsfulla felmeddelanden.
Exempeljobbet nedan läser en lokal XML-fil och försöker använda den med AxdCustomer-klassen (vilket är dokumentklassen som används av CustomCustomer-tjänsten) för att skapa en kund. Du kan göra liknande jobb för alla andra dokumentklasser, till exempel AxdSalesOrder, om du behöver.
{
FileNameOpen fileName = @'C:\\TestCustomerCreate.xml';
AxdCustomer customer;
AifEntityKey key;
#File
;
new FileIoPermission(fileName, #IO_Read).assert();
customer = new AxdCustomer();
key = customer.create( XmlDocument::newFile(fileName).xml(),
new AifEndpointActionPolicyInfo(),
new AifConstraintList());
CodeAccessPermission::revertAssert();
info('Done');
}
AifEntityKey-objektet som returneras av metoden customer.create() (som motsvarar tjänsten "create" i AIF) innehåller information om vilken kund som skapades, bland annat RecId för den skapade CustTable-posten.
Om det du försöker testa är en utgående port istället eller om du bara behöver ett exempel på hur XML ska se ut på den inkommande porten, kan du också använda dokumentklassen för att exportera en kund till en fil istället genom att anropa metoden read() (motsvarande tjänsten "läs") istället, som så:
{
FileNameSave fileName = @'C:\\TestCustomerRead.xml';
Map map = new Map( Types::Integer,
Types::Container);
AxdCustomer customer;
AifEntityKey key;
XMLDocument xmlDoc;
XML xml;
AifPropertyBag bag;
#File
;
map.insert(fieldNum(CustTable, AccountNum), ['123456']);
key = new AifEntityKey();
key.parmTableId(tableNum(CustTable));
key.parmKeyDataMap(map);
customer = new AxdCustomer();
xml = customer.read(key,
null,
new AifEndpointActionPolicyInfo(),
new AifConstraintList(),
bag);
new FileIoPermission(fileName, #IO_Write).assert();
xmlDoc = XmlDocument::newXml(xml);
xmlDoc.save(fileName);
CodeAccessPermission::revertAssert();
info('Done');
}
Du bör givetvis ersätta '123456' med kontonumret på den kund du vill läsa.