Miklix

Chiamata dei servizi di documentazione AIF direttamente da X++ in Dynamics AX 2012

Pubblicato: 16 febbraio 2025 alle ore 11:23:00 UTC

In questo articolo spiego come chiamare i servizi documentali dell'Application Integration Framework in Dynamics AX 2012 direttamente dal codice X++, emulando sia le chiamate in entrata che quelle in uscita, il che può semplificare notevolmente l'individuazione e il debug degli errori nel codice AIF.


Questa pagina è stata tradotta automaticamente dall'inglese per renderla accessibile al maggior numero di persone possibile. Purtroppo, la traduzione automatica non è ancora una tecnologia perfezionata, quindi possono verificarsi degli errori. Se preferite, potete consultare la versione originale in inglese qui:

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

Le informazioni contenute in questo post si basano su Dynamics AX 2012 R3. Potrebbero essere valide o meno per altre versioni.

Di recente ho aiutato un cliente a implementare una porta in entrata dell'Application Integration Framework (AIF) per creare clienti in base ai dati che ricevevano da un altro sistema. Poiché Dynamics AX fornisce già il servizio di documenti CustCustomer, che implementa la logica per questo, abbiamo deciso di semplificare e utilizzare la soluzione standard.

Tuttavia, si è scoperto presto che c'erano molti problemi nel far sì che il sistema esterno generasse XML che Dynamics AX avrebbe accettato. Lo schema XML generato da Dynamics AX è piuttosto complesso e sembra anche che ci siano alcuni bug in Dynamics AX che a volte gli fanno rifiutare XML che sono validi per lo schema secondo altri strumenti, quindi, tutto sommato, si è rivelato meno semplice di quanto pensassi.

Durante l'impresa, ho spesso faticato a capire quale fosse esattamente il problema con certi file XML perché i messaggi di errore forniti da AIF sono poco informativi. È stato anche noioso, perché ho dovuto aspettare che il sistema esterno inviasse un nuovo messaggio tramite MSMQ e poi di nuovo che AIF prendesse il messaggio e lo elaborasse prima che potessi vedere un errore.

Ho quindi verificato se fosse possibile chiamare il codice del servizio direttamente con un file XML locale per effettuare test un po' più rapidi e ho scoperto che è possibile. Non solo, è anche molto semplice da fare e fornisce messaggi di errore molto più significativi.

Il job di esempio qui sotto legge un file XML locale e prova a usarlo con la classe AxdCustomer (che è la classe di documento usata dal servizio CustCustomer) per creare un cliente. Puoi creare job simili per tutte le altre classi di documento, ad esempio AxdSalesOrder, se necessario.

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

L'oggetto AifEntityKey restituito dal metodo customer.create() (che corrisponde all'operazione di servizio "create" in AIF) contiene informazioni sul cliente che è stato creato, tra cui il RecId del record CustTable creato.

Se ciò che stai cercando di testare è una porta in uscita o se hai solo bisogno di un esempio di come dovrebbe apparire l'XML sulla porta in ingresso, puoi anche usare la classe documento per esportare un cliente in un file chiamando il metodo read() (corrispondente all'operazione di servizio "read"), in questo modo:

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

Naturalmente dovresti sostituire '123456' con il numero di conto del cliente che desideri leggere.

Condividi su BlueskyCondividi su FacebookCondividi su LinkedInCondividi su TumblrCondividi su XCondividi su LinkedInAggiungi su Pinterest

Mikkel Bang Christensen

Sull'autore

Mikkel Bang Christensen
Mikkel è il creatore e proprietario di miklix.com. Ha oltre 20 anni di esperienza come programmatore di computer/sviluppatore di software ed è attualmente impiegato a tempo pieno in una grande azienda IT europea. Quando non scrive sul blog, dedica il suo tempo libero a una vasta gamma di interessi, hobby e attività, che in qualche modo si riflettono nella varietà di argomenti trattati in questo sito.