Miklix

Chamar serviços de documentos AIF diretamente do X++ no Dynamics AX 2012

Publicado: 16 de fevereiro de 2025 às 11:23:11 UTC

Neste artigo, explico como chamar serviços de documentos do Application Integration Framework no Dynamics AX 2012 diretamente a partir do código X++, emulando chamadas de entrada e saída, o que pode tornar significativamente mais fácil encontrar e depurar erros no código AIF.


Esta página foi traduzida automaticamente do inglês para a tornar acessível ao maior número possível de pessoas. Infelizmente, a tradução automática ainda não é uma tecnologia aperfeiçoada, pelo que podem ocorrer erros. Se preferir, pode ver a versão original em inglês aqui:

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

As informações neste post são baseadas no Dynamics AX 2012 R3. Pode ou não ser válido para outras versões.

Recentemente, ajudei um cliente a implementar uma porta de entrada do Application Integration Framework (AIF) para criar clientes com base em dados que estavam a receber de outro sistema. Como o Dynamics AX já fornece o serviço de documentos CustCustomer, que implementa a lógica para tal, decidimos mantê-lo simples e utilizar a solução padrão.

No entanto, cedo descobrimos que existiam muitos problemas para fazer com que o sistema externo gerasse XML que o Dynamics AX aceitasse. O esquema XML gerado pelo Dynamics AX é bastante complexo e também parece haver alguns bugs no Dynamics AX que por vezes o fazem rejeitar XML cujo esquema é válido de acordo com outras ferramentas, pelo que, no geral, provou ser menos simples do que eu pensava.

Durante o processo, muitas vezes tive dificuldade em descobrir qual era exatamente o problema com determinados ficheiros XML porque as mensagens de erro fornecidas pelo AIF são pouco informativas. Também era tedioso, porque tinha de esperar que o sistema externo enviasse uma nova mensagem através do MSMQ e depois novamente para o AIF receber a mensagem e processá-la antes de poder ver um erro.

Por isso, investiguei se é possível chamar o código de serviço diretamente com um ficheiro XML local para testes um pouco mais rápidos e descobri que é possível.

O trabalho de exemplo abaixo lê um ficheiro XML local e tenta utilizá-lo com a classe AxdCustomer (que é a classe de documento utilizada pelo serviço CustCustomer) para criar um cliente. Pode criar tarefas semelhantes para todas as outras classes de documentos, por exemplo AxdSalesOrder, se necessário.

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');
}

O objeto AifEntityKey devolvido pelo método customer.create() (que corresponde à operação de serviço "create" no AIF) contém informação sobre qual o cliente que foi criado, entre outras coisas, o RecId do registo CustTable criado.

Se o que está a tentar testar é uma porta de saída ou se apenas necessita de um exemplo de como o XML deve ficar na porta de entrada, também pode utilizar a classe document para exportar um cliente para um ficheiro chamando o método read() (correspondente à operação de serviço "read"), assim:

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');
}

É claro que deve substituir '123456' pelo número de conta do cliente que pretende ler.

Leitura adicional

Se gostou deste post, também pode gostar destas sugestões:


Partilhar no BlueskyPartilhar no FacebookPartilhar no LinkedInPartilhar no TumblrPartilhar em XPartilhar no LinkedInFixar no Pinterest

Mikkel Christensen

Sobre o autor

Mikkel Christensen
Mikkel é o criador e proprietário do miklix.com. Tem mais de 20 anos de experiência como programador informático/desenvolvedor de software profissional e trabalha atualmente a tempo inteiro para uma grande empresa europeia de TI. Quando não está a escrever no blogue, dedica o seu tempo livre a um vasto leque de interesses, passatempos e actividades, que podem, em certa medida, refletir-se na variedade de tópicos abordados neste sítio Web.