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
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.
Calling AIF Document Services Directly from X++ in Dynamics AX 2012
La información de este artículo se basa en Dynamics AX 2012 R3. Puede que sea válida o no para otras versiones.
Recientemente estuve ayudando a un cliente a implementar un puerto de entrada de Application Integration Framework (AIF) para crear clientes en función de los datos que recibían de otro sistema. Como Dynamics AX ya proporciona el servicio de documentos CustCustomer, que implementa la lógica para esto, decidimos simplificarlo y utilizar la solución estándar.
Sin embargo, pronto resultó que había muchos problemas para lograr que el sistema externo generara XML que Dynamics AX aceptara. El esquema XML generado por Dynamics AX es bastante complejo y también parece que hay algunos errores en Dynamics AX que a veces hacen que rechace XML que es válido para el esquema según otras herramientas, por lo que, en general, resultó ser menos simple de lo que pensaba.
Durante el proceso, me costó mucho averiguar cuál era exactamente el problema con determinados archivos XML, ya que los mensajes de error que proporciona AIF no son del todo informativos. También era tedioso, porque tenía que esperar a que el sistema externo enviara un nuevo mensaje a través de MSMQ y luego a que AIF lo recogiera y lo procesara antes de que pudiera ver 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 trabajo de ejemplo que se muestra a continuación lee un archivo XML local e intenta usarlo con la clase AxdCustomer (que es la clase de documento que utiliza el servicio CustCustomer) para crear un cliente. Puede realizar trabajos similares para todas las demás clases de documentos, por ejemplo, AxdSalesOrder, si lo necesita.
{
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:
{
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.