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.
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.
{
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:
{
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.