Miklix

Виклик служб документообігу AIF безпосередньо з X++ у Dynamics AX 2012

Опубліковано: 16 лютого 2025 р. о 11:23:18 UTC
Останнє оновлення: 12 січня 2026 р. о 08:55:25 UTC

У цій статті я пояснюю, як викликати служби документів Application Integration Framework у Dynamics AX 2012 безпосередньо з коду X++, емулюючи як вхідні, так і вихідні виклики, що може значно спростити пошук і налагодження помилок у коді AIF.


Ця сторінка була перекладена з англійської мови машинним перекладом, щоб зробити її доступною для якомога більшої кількості людей. На жаль, машинний переклад ще не є досконалою технологією, тому можуть траплятися помилки. Якщо ви бажаєте, ви можете переглянути оригінальну англійську версію тут:

Calling AIF Document Services Directly from X++ in Dynamics AX 2012

Інформація в цій публікації базується на Dynamics AX 2012 R3. Вона може бути актуальною для інших версій, а може й ні.

Нещодавно я допомагав клієнту впроваджувати вхідний порт Application Integration Framework (AIF) для створення клієнтів на основі даних, які вони отримували з іншої системи. Оскільки Dynamics AX вже надає службу документів CustCustomer, яка реалізує логіку для цього, ми вирішили спростити його та використовувати стандартне рішення.

Однак, невдовзі виявилося, що виникло багато проблем зі створенням зовнішньою системою XML, який би приймала Dynamics AX. Схема XML, згенерована Dynamics AX, є досить складною, і, схоже, в Dynamics AX є кілька помилок, які іноді призводять до відхилення XML, який є допустимим за схемою згідно з іншими інструментами, тому загалом все виявилося менш простим, ніж я думав.

Під час цих зусиль мені часто було важко зрозуміти, у чому саме полягала проблема з певними XML-файлами, оскільки повідомлення про помилки, що надаються AIF, були не дуже інформативними. Це також було нудно, оскільки мені доводилося чекати, поки зовнішня система надішле нове повідомлення через MSMQ, а потім знову, поки AIF прийме повідомлення та обробить його, перш ніж я побачив помилку.

Тому я дослідив, чи можливо викликати код служби безпосередньо з локального XML-файлу для дещо швидшого тестування, і виявилося, що це можливо - і більше того, це дуже просто зробити, і насправді це надає набагато більше змістовних повідомлень про помилки.

У наведеному нижче прикладі завдання зчитується локальний XML-файл і намагається використати його з класом AxdCustomer (класом документів, що використовується службою CustCustomer) для створення клієнта. За потреби ви можете створити аналогічні завдання для всіх інших класів документів, наприклад, AxdSalesOrder.

static void CustomerCreate(Args _args)
{
    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, що повертається методом customer.create() (що відповідає операції служби "create" в AIF), містить інформацію про те, який клієнт був створений, серед іншого, RecId створеного запису CustTable.

Якщо ви намагаєтеся протестувати вихідний порт або вам просто потрібен приклад того, як має виглядати XML на вхідному порту, ви також можете використовувати клас документа для експорту клієнта у файл, викликавши метод read() (що відповідає операції служби "читання"), ось так:

static void CustomerRead(Args _args)
{
    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');
}

Звичайно, вам слід замінити «123456» номером рахунку клієнта, дані якого ви хочете прочитати.

Додаткова література

Якщо вам сподобався цей пост, вам також можуть сподобатися ці пропозиції:


Поділитися на BlueskyПоділіться на FacebookПоділіться на LinkedInПоділіться на TumblrПоділитися на XПоділіться на LinkedInЗакріпити на Pinterest

Міккель Крістенсен

Про автора

Міккель Крістенсен
Міккель - творець і власник сайту miklix.com. Він має понад 20 років досвіду роботи професійним програмістом/розробником програмного забезпечення і наразі працює на повну ставку у великій європейській ІТ-корпорації. У вільний від ведення блогу час він присвячує різноманітним інтересам, хобі та захопленням, що певною мірою відображається на різноманітності тем, які висвітлюються на цьому сайті.