Miklix

Ringer AIF Document Services direkt från X++ i Dynamics AX 2012

Publicerad: 16 februari 2025 kl. 11:23:16 UTC

I den här artikeln förklarar jag hur man anropar Application Integration Framework-dokumenttjänster i Dynamics AX 2012 direkt från X++-kod, som emulerar både inkommande och utgående samtal, vilket kan göra det betydligt lättare att hitta och felsöka fel i AIF-kod.


Denna sida har maskinöversatts från engelska för att göra den tillgänglig för så många som möjligt. Tyvärr är maskinöversättning ännu inte en fulländad teknik, så fel kan uppstå. Om du föredrar det kan du se den engelska originalversionen här:

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

Informationen i det här inlägget är baserad på Dynamics AX 2012 R3. Det kan eller kanske inte är giltigt för andra versioner.

Jag hjälpte nyligen en kund att implementera en inkommande port för Application Integration Framework (AIF) för att skapa kunder baserat på data som de fick från ett annat system. Eftersom Dynamics AX redan tillhandahåller dokumenttjänsten CustomCustomer, som implementerar logiken för detta, bestämde vi oss för att hålla det enkelt och använda standardlösningen.

Det visade sig dock snart att det fanns en hel del problem att få det externa systemet att generera XML som Dynamics AX skulle acceptera. XML-schemat som genereras av Dynamics AX är ganska komplext och det verkar också finnas få buggar i Dynamics AX som ibland gör att det avvisar XML som är schemagiltigt enligt andra verktyg, så allt som allt visade det sig vara mindre enkelt än jag hade trott.

Under strävan kämpade jag ofta för att komma på exakt vad problemet var med vissa XML-filer eftersom felmeddelandena från AIF är mindre informativa. Det var också tråkigt, eftersom jag var tvungen att vänta på att det externa systemet skulle skicka ett nytt meddelande över MSMQ och sedan igen för att AIF skulle hämta meddelandet och bearbeta det innan jag kunde se ett fel.

Jag undersökte därför om det är möjligt att anropa servicekoden direkt med en lokal XML-fil för något snabbare testning och det visar sig att det är det – och inte bara det, det är väldigt enkelt att göra och ger faktiskt mycket mer meningsfulla felmeddelanden.

Exempeljobbet nedan läser en lokal XML-fil och försöker använda den med AxdCustomer-klassen (vilket är dokumentklassen som används av CustomCustomer-tjänsten) för att skapa en kund. Du kan göra liknande jobb för alla andra dokumentklasser, till exempel AxdSalesOrder, om du behöver.

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 som returneras av metoden customer.create() (som motsvarar tjänsten "create" i AIF) innehåller information om vilken kund som skapades, bland annat RecId för den skapade CustTable-posten.

Om det du försöker testa är en utgående port istället eller om du bara behöver ett exempel på hur XML ska se ut på den inkommande porten, kan du också använda dokumentklassen för att exportera en kund till en fil istället genom att anropa metoden read() (motsvarande tjänsten "läs") istället, som så:

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 givetvis ersätta '123456' med kontonumret på den kund du vill läsa.

Dela på BlueskyDela på FacebookDela på LinkedInDela på TumblrDela på XDela på LinkedInFäst på Pinterest

Mikkel Bang Christensen

Om författaren

Mikkel Bang Christensen
Mikkel är skaparen och ägaren av miklix.com. Han har över 20 års erfarenhet som professionell datorprogrammerare/mjukvaruutvecklare och är för närvarande heltidsanställd på ett stort europeiskt IT-bolag. När han inte bloggar ägnar han sin fritid åt en mängd olika intressen, hobbies och aktiviteter, vilket i viss mån kan återspeglas i de olika ämnen som behandlas på den här webbplatsen.