Miklix

Wywoływanie usług dokumentów AIF bezpośrednio z X++ w Dynamics AX 2012

Opublikowano: 16 lutego 2025 11:23:09 UTC
Ostatnia aktualizacja: 12 stycznia 2026 08:55:20 UTC

W tym artykule wyjaśnię, jak wywoływać usługi dokumentów Application Integration Framework w systemie Dynamics AX 2012 bezpośrednio z kodu X++, emulując zarówno połączenia przychodzące, jak i wychodzące, co może znacznie ułatwić znajdowanie i debugowanie błędów w kodzie AIF.


Ta strona została przetłumaczona maszynowo z języka angielskiego, aby była dostępna dla jak największej liczby osób. Niestety, tłumaczenie maszynowe nie jest jeszcze dopracowaną technologią, więc mogą wystąpić błędy. Jeśli wolisz, możesz wyświetlić oryginalną angielską wersję tutaj:

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

Informacje zawarte w tym poście dotyczą systemu Dynamics AX 2012 R3. Mogą być lub nie być aktualne dla innych wersji.

Niedawno pomagałem klientowi wdrożyć port wejściowy Application Integration Framework (AIF) do tworzenia klientów na podstawie danych otrzymywanych z innego systemu. Ponieważ Dynamics AX oferuje już usługę dokumentów CustCustomer, która implementuje logikę tego procesu, postanowiliśmy postawić na prostotę i zastosować standardowe rozwiązanie.

Szybko jednak okazało się, że istnieje wiele problemów z wygenerowaniem przez system zewnętrzny pliku XML, który Dynamics AX akceptował. Schemat XML generowany przez Dynamics AX jest dość złożony, a poza tym w Dynamics AX występuje kilka błędów, które czasami powodują odrzucanie plików XML zgodnych ze schematem według innych narzędzi. Podsumowując, okazało się to mniej proste, niż myślałem.

Podczas tego przedsięwzięcia często miałem problem ze zrozumieniem, na czym dokładnie polega problem z niektórymi plikami XML, ponieważ komunikaty o błędach dostarczane przez AIF były mało informacyjne. Było to również żmudne, ponieważ musiałem czekać, aż system zewnętrzny wyśle nową wiadomość przez MSMQ, a następnie ponownie, aż AIF ją odbierze i przetworzy, zanim zobaczyłem błąd.

Zbadałem zatem, czy możliwe jest wywołanie kodu usługi bezpośrednio z lokalnego pliku XML w celu przyspieszenia testów. Okazało się, że jest to możliwe. Co więcej, jest to naprawdę proste rozwiązanie, a komunikaty o błędach są znacznie bardziej zrozumiałe.

Poniższe przykładowe zadanie odczytuje lokalny plik XML i próbuje go użyć z klasą AxdCustomer (która jest klasą dokumentu używaną przez usługę CustCustomer), aby utworzyć klienta. W razie potrzeby możesz utworzyć podobne zadania dla wszystkich innych klas dokumentów, na przykład AxdSalesOrder.

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

Obiekt AifEntityKey zwrócony przez metodę customer.create() (odpowiadającą operacji usługi „create” w AIF) zawiera informacje o tym, który klient został utworzony, a także między innymi identyfikator RecId utworzonego rekordu CustTable.

Jeśli zamiast tego próbujesz przetestować port wychodzący lub po prostu potrzebujesz przykładu, jak powinien wyglądać kod XML na porcie przychodzącym, możesz również użyć klasy document do wyeksportowania klienta do pliku, wywołując metodę read() (odpowiadającą operacji usługi „read”) w następujący sposób:

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

Oczywiście należy zastąpić liczbę „123456” numerem konta klienta, którego dane chcesz odczytać.

Dalsza lektura

Jeśli podobał Ci się ten wpis, mogą Cię zainteresować również poniższe sugestie:


Udostępnij na BlueskyUdostępnij na FacebookuUdostępnij na LinkedInUdostępnij na TumblrUdostępnij na XUdostępnij na LinkedInPrzypnij na Pintereście

Mikkel Christensen

O autorze

Mikkel Christensen
Mikkel jest twórcą i właścicielem miklix.com. Ma ponad 20-letnie doświadczenie jako profesjonalny programista komputerowy / programista oprogramowania i jest obecnie zatrudniony na pełny etat w dużej europejskiej korporacji IT. Kiedy nie bloguje, poświęca swój wolny czas na szeroki wachlarz zainteresowań, hobby i aktywności, co może w pewnym stopniu znaleźć odzwierciedlenie w różnorodności tematów poruszanych na tej stronie.