Miklix

在 Dynamics AX 2012 中直接从 X++ 调用 AIF 文档服务

已出版: 2025年2月16日 UTC 11:23:22
最后更新 2026年1月12日 UTC 08:55:26

在本文中,我将解释如何直接从 X++ 代码调用 Dynamics AX 2012 中的应用程序集成框架文档服务,模拟入站和出站调用,这可以大大简化查找和调试 AIF 代码中的错误。


为了使尽可能多的人能够访问本页面,本页面由英文机译而成。遗憾的是,机器翻译技术尚不完善,因此可能会出现错误。如果您愿意,可以在此处查看原始英文版本:

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

本文中的信息基于 Dynamics AX 2012 R3 版本,可能不适用于其他版本。

我最近在帮助一位客户实施一个应用程序集成框架 (AIF) 入站端口,用于根据从另一个系统接收的数据创建客户。由于 Dynamics AX 已经提供了 CustCustomer 文档服务来实现这一逻辑,我们决定简化流程,使用标准解决方案。

然而,很快我就发现,要让外部系统生成Dynamics AX能够接受的XML文件,存在诸多问题。Dynamics AX生成的XML架构相当复杂,而且Dynamics AX本身似乎也存在一些bug,有时会导致它拒绝其他工具识别为架构有效的XML文件。总而言之,这比我想象的要复杂得多。

在这个过程中,我经常难以确定某些 XML 文件究竟出了什么问题,因为 AIF 提供的错误信息不够详细。而且,这也很繁琐,因为我必须先等待外部系统通过 MSMQ 发送新消息,然后再等待 AIF 接收并处理该消息,之后才能看到错误信息。

因此,我调查了是否可以使用本地 XML 文件直接调用服务代码以加快测试速度,结果发现是可以的——不仅如此,这样做还非常简单,并且实际上提供了更有意义的错误消息。

以下示例作业读取本地 XML 文件,并尝试将其与 AxdCustomer 类(CustCustomer 服务使用的文档类)一起使用以创建客户。如有需要,您可以为所有其他文档类(例如 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');
}

customer.create() 方法(对应于 AIF 中的“创建”服务操作)返回的 AifEntityKey 对象包含有关创建哪个客户的信息,其中包括创建的 CustTable 记录的 RecId。

如果您要测试的是出站端口,或者您只是需要一个入站端口 XML 的示例,您也可以使用文档类,通过调用 read() 方法(对应于“读取”服务操作)将客户导出到文件,如下所示:

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

当然,您应该将“123456”替换为您要查看的客户账号。

进一步阅读

如果您喜欢这篇文章,您可能还会喜欢这些建议:


分享至 Bluesky在 Facebook 上分享在 LinkedIn 上分享在 Tumblr 上分享分享至 X在 LinkedIn 上分享在Pinterest上固定

Mikkel Christensen

关于作者

Mikkel Christensen
迈克尔 是 miklix.com 的创建者和所有者。他拥有 20 多年的专业计算机程序员/软件开发人员经验,目前全职受雇于一家大型欧洲 IT 公司。不写博客时,他把业余时间花在各种兴趣、爱好和活动上,这在一定程度上反映在本网站涵盖的各种主题上。