Miklix

Вызов служб документов AIF напрямую из X++ в Dynamics AX 2012

Опубликовано: 16 февраля 2025 г. в 11:23:12 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-летний опыт работы в качестве профессионального программиста/разработчика программного обеспечения и в настоящее время работает на полную ставку в крупной европейской IT-корпорации. Когда он не ведет блог, то тратит свое свободное время на огромное количество интересов, хобби и занятий, что в некоторой степени отражается в разнообразии тем, освещаемых на этом сайте.