Miklix

Gọi AIF Document Services trực tiếp từ X++ trong Dynamics AX 2012

Đã xuất bản: lúc 11:23:31 UTC 16 tháng 2, 2025
Cập nhật lần cuối: lúc 08:55:29 UTC 12 tháng 1, 2026

Trong bài viết này, tôi sẽ giải thích cách gọi trực tiếp các dịch vụ tài liệu của Khung tích hợp ứng dụng (Application Integration Framework - AIF) trong Dynamics AX 2012 từ mã X++, mô phỏng cả các cuộc gọi đến và đi, điều này có thể giúp việc tìm và gỡ lỗi trong mã AIF trở nên dễ dàng hơn đáng kể.


Trang này được dịch máy từ tiếng Anh để có thể tiếp cận được với nhiều người nhất có thể. Thật không may, dịch máy vẫn chưa phải là công nghệ hoàn thiện, do đó có thể xảy ra lỗi. Nếu bạn thích, bạn có thể xem phiên bản tiếng Anh gốc tại đây:

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

Thông tin trong bài viết này dựa trên Dynamics AX 2012 R3. Thông tin này có thể không còn đúng đối với các phiên bản khác.

Gần đây, tôi đã hỗ trợ một khách hàng triển khai cổng đầu vào của Khung tích hợp ứng dụng (AIF) để tạo khách hàng dựa trên dữ liệu họ nhận được từ một hệ thống khác. Vì Dynamics AX đã cung cấp dịch vụ tài liệu CustCustomer, vốn đã thực hiện logic này, nên chúng tôi quyết định giữ cho mọi thứ đơn giản và sử dụng giải pháp tiêu chuẩn.

Tuy nhiên, chẳng mấy chốc, người ta nhận ra rằng có rất nhiều vấn đề khi cố gắng khiến hệ thống bên ngoài tạo ra XML mà Dynamics AX chấp nhận. Lược đồ XML do Dynamics AX tạo ra khá phức tạp và dường như cũng có một vài lỗi trong Dynamics AX đôi khi khiến nó từ chối XML hợp lệ theo các công cụ khác, vì vậy tóm lại, mọi việc hóa ra không đơn giản như tôi tưởng.

Trong quá trình thực hiện, tôi thường gặp khó khăn trong việc tìm ra chính xác vấn đề với một số tệp XML nhất định vì các thông báo lỗi do AIF cung cấp không đầy đủ thông tin. Điều này cũng rất tốn thời gian, vì tôi phải đợi hệ thống bên ngoài gửi một tin nhắn mới qua MSMQ và sau đó lại phải đợi AIF nhận và xử lý tin nhắn đó trước khi tôi có thể thấy lỗi.

Do đó, tôi đã tìm hiểu xem liệu có thể gọi trực tiếp mã dịch vụ bằng tệp XML cục bộ để kiểm tra nhanh hơn một chút hay không, và hóa ra là có thể - và không chỉ vậy, việc này thực sự rất đơn giản và còn cung cấp các thông báo lỗi có ý nghĩa hơn nhiều.

Ví dụ công việc bên dưới đọc một tệp XML cục bộ và cố gắng sử dụng nó với lớp AxdCustomer (là lớp tài liệu được dịch vụ CustCustomer sử dụng) để tạo khách hàng. Bạn có thể tạo các công việc tương tự cho tất cả các lớp tài liệu khác, ví dụ như AxdSalesOrder, nếu cần.

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

Đối tượng AifEntityKey được trả về bởi phương thức customer.create() (tương ứng với thao tác dịch vụ "create" trong AIF) chứa thông tin về khách hàng nào đã được tạo, trong đó có RecId của bản ghi CustTable được tạo.

Nếu bạn đang cố gắng kiểm tra cổng Outbound hoặc nếu bạn chỉ cần một ví dụ về cách XML sẽ trông như thế nào trên cổng Inbound, bạn cũng có thể sử dụng lớp document để xuất thông tin khách hàng ra tệp bằng cách gọi phương thức read() (tương ứng với thao tác dịch vụ "read"), như sau:

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

Tất nhiên, bạn nên thay thế '123456' bằng số tài khoản của khách hàng mà bạn muốn xem thông tin.

Đọc thêm

Nếu bạn thích bài viết này, bạn cũng có thể thích những gợi ý sau:


Chia sẻ trên BlueskyChia sẻ trên FacebookChia sẻ trên LinkedInChia sẻ trên TumblrChia sẻ trên XChia sẻ trên LinkedInGhim trên Pinterest

Mikkel Christensen

Về tác giả

Mikkel Christensen
Mikkel là người sáng lập và chủ sở hữu của miklix.com. Ông có hơn 20 năm kinh nghiệm làm lập trình viên máy tính/nhà phát triển phần mềm chuyên nghiệp và hiện đang làm việc toàn thời gian cho một tập đoàn CNTT lớn của Châu Âu. Khi không viết blog, ông dành thời gian rảnh rỗi cho nhiều sở thích, thú vui và hoạt động, có thể được phản ánh ở một mức độ nào đó trong nhiều chủ đề được đề cập trên trang web này.