Miklix

Ringe AIF Document Services direkte fra X++ i Dynamics AX 2012

Publisert: 16. februar 2025 kl. 11:23:06 UTC

I denne artikkelen forklarer jeg hvordan du kaller Application Integration Framework-dokumenttjenester i Dynamics AX 2012 direkte fra X++-kode, og emulerer både innkommende og utgående samtaler, noe som kan gjøre det betydelig enklere å finne og feilsøke feil i AIF-kode.


Denne siden er maskinoversatt fra engelsk for å gjøre den tilgjengelig for så mange som mulig. Dessverre er maskinoversettelse ennå ikke en fullkommen teknologi, så det kan forekomme feil. Hvis du foretrekker det, kan du se den engelske originalversjonen her:

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

Informasjonen i dette innlegget er basert på Dynamics AX 2012 R3. Det kan være eller ikke være gyldig for andre versjoner.

Jeg hjalp nylig en kunde med å implementere en inngående port for Application Integration Framework (AIF) for å opprette kunder basert på data de mottok fra et annet system. Siden Dynamics AX allerede leverer dokumenttjenesten CustomCustomer, som implementerer logikken for dette, bestemte vi oss for å holde det enkelt og bruke standardløsningen.

Det viste seg imidlertid fort at det var mange problemer med å få det eksterne systemet til å generere XML som Dynamics AX ville akseptere. XML-skjemaet generert av Dynamics AX er ganske komplekst, og det ser også ut til at det er få feil i Dynamics AX som noen ganger får det til å avvise XML som er skjemagyldig i henhold til andre verktøy, så alt i alt viste det seg å være mindre enkelt enn jeg hadde trodd.

Under forsøket slet jeg ofte med å finne ut nøyaktig hva problemet var med visse XML-filer fordi feilmeldingene fra AIF er mindre enn informative. Det var også kjedelig, fordi jeg måtte vente på at det eksterne systemet skulle sende en ny melding over MSMQ og så igjen på at AIF skulle plukke opp meldingen og behandle den før jeg kunne se en feil.

Jeg undersøkte derfor om det er mulig å ringe tjenestekoden direkte med en lokal XML-fil for noe raskere testing og det viser seg at det er det – og ikke bare det, det er veldig enkelt å gjøre og gir faktisk mye mer meningsfulle feilmeldinger.

Eksempeljobben nedenfor leser en lokal XML-fil og prøver å bruke den med AxdCustomer-klassen (som er dokumentklassen som brukes av Customer-tjenesten) for å opprette en kunde. Du kan lage lignende jobber for alle de andre dokumentklassene, for eksempel AxdSalesOrder, hvis du trenger det.

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-objektet returnert av customer.create()-metoden (som tilsvarer "create"-tjenesteoperasjonen i AIF) inneholder informasjon om hvilken kunde som ble opprettet, blant annet RecId for den opprettede CustTable-posten.

Hvis det du prøver å teste er en utgående port i stedet, eller hvis du bare trenger et eksempel på hvordan XML-en skal se ut på den inngående porten, kan du også bruke dokumentklassen til å eksportere en kunde til en fil i stedet ved å kalle read()-metoden (tilsvarende "read"-tjenesteoperasjonen) i stedet, slik:

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

Du bør selvfølgelig erstatte '123456' med kontonummeret til kunden du ønsker å lese.

Del på BlueskyDel på FacebookDel på LinkedInDel på TumblrDel på XDel på LinkedInFest på Pinterest

Mikkel Bang Christensen

Om forfatteren

Mikkel Bang Christensen
Mikkel er skaperen og eieren av miklix.com. Han har over 20 års erfaring som profesjonell dataprogrammerer/programvareutvikler og er for tiden ansatt på fulltid i et stort europeisk IT-selskap. Når han ikke blogger, bruker han fritiden sin på en lang rekke interesser, hobbyer og aktiviteter, noe som til en viss grad kan gjenspeiles i de mange ulike temaene som dekkes på dette nettstedet.