Miklix

Cómo llamar a servicios de documentos AIF directamente desde X++ en Dynamics AX 2012

Publicado: 16 de febrero de 2025, 11:22:55 UTC
Última actualización: 12 de enero de 2026, 8:55:12 UTC

En este artículo, explico cómo llamar a los servicios de documentos de Application Integration Framework en Dynamics AX 2012 directamente desde el código X++, emulando llamadas entrantes y salientes, lo que puede facilitar significativamente la búsqueda y depuración de errores en el código AIF.


Esta página ha sido traducida automáticamente del inglés para hacerla accesible al mayor número de personas posible. Lamentablemente, la traducción automática no es todavía una tecnología perfeccionada, por lo que pueden producirse errores. Si lo prefiere, puede consultar la versión original en inglés aquí:

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

La información de esta publicación se basa en Dynamics AX 2012 R3. Puede que no sea válida para otras versiones.

Recientemente ayudé a un cliente a implementar un puerto de entrada de Application Integration Framework (AIF) para crear clientes a partir de los datos que recibían de otro sistema. Dado que Dynamics AX ya ofrece el servicio de documentos CustCustomer, que implementa la lógica para esto, decidimos simplificarlo y usar la solución estándar.

Sin embargo, pronto se descubrió que existían muchos problemas para que el sistema externo generara XML que Dynamics AX aceptara. El esquema XML generado por Dynamics AX es bastante complejo y, al parecer, también presenta algunos errores que a veces hacen que rechace XML válido según otras herramientas. En resumen, resultó ser más complicado de lo que pensaba.

Durante el proceso, a menudo me costaba averiguar cuál era exactamente el problema con ciertos archivos XML, ya que los mensajes de error de AIF no eran muy informativos. Además, era tedioso, ya que tenía que esperar a que el sistema externo enviara un nuevo mensaje por MSMQ y luego a que AIF lo recogiera y lo procesara antes de que pudiera detectar un error.

Por lo tanto, investigué si es posible llamar al código de servicio directamente con un archivo XML local para realizar pruebas un poco más rápidas y resulta que sí lo es, y no solo eso, es realmente simple de hacer y, de hecho, proporciona mensajes de error mucho más significativos.

El siguiente trabajo de ejemplo lee un archivo XML local e intenta usarlo con la clase AxdCustomer (la clase de documento que utiliza el servicio CustCustomer) para crear un cliente. Puede crear trabajos similares para todas las demás clases de documento, por ejemplo, AxdSalesOrder, si lo necesita.

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

El objeto AifEntityKey devuelto por el método customer.create() (que corresponde a la operación de servicio "crear" en AIF) contiene información sobre qué cliente fue creado, entre otras cosas el RecId del registro CustTable creado.

Si lo que estás intentando probar es un puerto de salida o si solo necesitas un ejemplo de cómo debería verse el XML en el puerto de entrada, también puedes usar la clase de documento para exportar un cliente a un archivo en su lugar llamando al método read() (correspondiente a la operación de servicio "leer"), de la siguiente manera:

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

Por supuesto, debe reemplazar '123456' con el número de cuenta del cliente que desea leer.

Lectura adicional

Si te ha gustado esta publicación, puede que también te gusten estas sugerencias:


Compartir en BlueskyCompartir en FacebookCompartir en LinkedInCompartir en TumblrCompartir en XCompartir en LinkedInPin en Pinterest

Mikkel Christensen

Sobre el autor

Mikkel Christensen
Mikkel es el creador y propietario de miklix.com. Tiene más de 20 años de experiencia como programador informático profesional y desarrollador de software, y actualmente trabaja a tiempo completo para una gran empresa europea de TI. Cuando no está escribiendo en su blog, dedica su tiempo libre a una gran variedad de intereses, aficiones y actividades, que en cierta medida pueden verse reflejados en la variedad de temas tratados en este sitio web.