Cómo conectar Power Apps con Dynamics AX 2012 (I)

En esta serie de artículos aprenderemos a conectar una PowerApp con Dynamics AX 2012, pasando por cada uno de los requisitos necesarios para disponer de una conexión online y bidireccional entre los dos sistemas.

Dado que no existe un conector específico para Dynamics AX 2012, la primera opción en la que pensamos para conectar los dos sistemas es utilizando el conector SQL de Power Apps. Es una opción válida para recuperar información de Dynamics, pero no para escribir, ya que tendríamos que tratar manualmente campos como el RecId, TableId ,etc… además de todas las validaciones que Dynamics realiza por defecto, como por ejemplo la validación de campos obligatorios.

Teniendo en cuenta esta limitación, la mejor opción para conectar los dos sistemas, sin replicar información en bases de datos intermedias, pasa por crear un conector personalizado en Power App que consuma un servicio web creado en Dynamics.

En esta primera parte pues, nos centraremos en crear este conector. No obstante, hay que tener en cuenta que los servicios web de Dynamics AX 2012 son de tipo SOAP, mientras que los conectores personalizados de Power Apps requieren el uso de APIs de tipo REST, por lo que será necesario transformar el servicio web generado en Dynamics.

Nuestro primer objetivo será entonces crear un servicio web en Dynamics AX2012. Empezaremos creando un servicio que nos devuelva el código y el nombre de todos nuestros clientes. Para ello, será necesario crear 2 clases en X++:

1. Crear clase PowerAppCustomerService

class PowerAppCustomerService
{
}

[SysEntryPointAttribute(true),
AifCollectionTypeAttribute('return', Types::Class, classStr(PowerAppCustomerDC))]
public List getCustomers()
{
    List                        ret = new List(types::Class);
    PowerAppCustomerDC          customerDC;
    CustTable                   custTable;

    while select custTable
    {
        customerDC = new PowerAppCustomerDC();
        customerDC.parmCustAccount(custTable.AccountNum);
        customerDC.parmCustName(custTable.name());

        ret.addEnd(customerDC);
    }

    return ret;
}

2. Crear clase PowerAppCustomerDC

[DataContractAttribute]
class PowerAppCustomerDC
{
    CustAccount custAccount;
    CustName    custName;
}

[DataMemberAttribute("CustAccount")]
public CustAccount parmCustAccount(CustAccount _custAccount = custAccount)
{
    custAccount =_custAccount;
    return custAccount;
}

[DataMemberAttribute("CustName")]
public CustName parmCustName(CustName _custName = custName)
{
    custName = _custName;
    return custName;
}

3. Crear servicio

Una vez creadas las clases, necesitaremos crear un servicio añadiendo la operación getCustomers que tenemos en la clase PowerAppCustomerService:


4. Crear grupo de servicios

Para terminar con la creación del servicio web, tendremos que crear e implementar un grupo de servicios, en el que agregaremos el servicio creado en el punto anterior:


Al implementar el grupo, el sistema creará automáticamente un puerto de entrada en el que podremos obtener la URL del servicio web.

5. Crear Web API

Ya tenemos nuestro servicio web operativo, pero tal y como hemos comentado en la introducción, será necesario transformar este servicio utilizando REST. Para tal propósito, crearemos una Web API desde Visual Studio.


Una vez creado el proyecto, añadiremos una referencia de servicio con la URL del servicio web creado en Dynamics:

Posteriormente, añadiremos un nuevo controlador con el siguiente código:


using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;
using PowerAppCustomer.DynamicsWS;

namespace PowerAppCustomer.Controllers
{
    public class DynamicsController : ApiController
    {        
        [HttpGet]
        [Route("GetCustomers")]
        public HttpResponseMessage GetCustomers()
        {            
            CallContext callContext = new CallContext();

            callContext.Company = "DAT";
            callContext.Language = "en-us";

            PowerAppCustomerServiceClient client = new PowerAppCustomerServiceClient();            

            PowerAppCustomerDC[] customers = client.getCustomers(callContext);
            List<PowerAppCustomerDC> list = new List<PowerAppCustomerDC>();
            foreach (var item in customers)
            {
                list.Add(item);
            }

            return Request.CreateResponse(HttpStatusCode.OK, list);
        }
    }
}

Por último, necesitamos que el resultado sea en formato JSON, por lo que modificaremos el archivo WebApiConfig.cs, dejándolo de la siguiente forma:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Http;

namespace PowerAppCustomer
{
    public static class WebApiConfig
    {
        public static void Register(HttpConfiguration config)
        {
            // Configuración y servicios de API web

            // Rutas de API web
            config.MapHttpAttributeRoutes();

            config.Routes.MapHttpRoute(
                name: "DefaultApi",
                routeTemplate: "api/{controller}/{id}",
                defaults: new { id = RouteParameter.Optional }
            );

            var appXmlType = config.Formatters.XmlFormatter.SupportedMediaTypes.FirstOrDefault(t => t.MediaType == "application/xml");
            config.Formatters.XmlFormatter.SupportedMediaTypes.Remove(appXmlType);
        }
    }
}

6. Publicar servicio en IIS

Ya tenemos nuestra Web API en formato JSON, por lo que ya podemos publicar el servicio en IIS para que este sea accesible desde fuera del dominio:

  • Copiar la Web API en la carpeta C:/inetpub/wwwrooot
  • Crear un sitio web en IIS, que apunte a esta carpeta

Es imprescindible asegurarnos de que el puerto usado es accesible desde fuera del dominio. Para tal propósito, tendremos que revisar la configuración de nuestro router y firewall.

Por último, revisamos que el servicio web se ha publicado correctamente, y que el resultado devuelto sea en formato JSON (esta prueba la deberíamos realizar desde fuera del dominio de nuestro IIS):

7. Crear conector personalizado en Power Apps

Ahora sí, estamos en condiciones de crear un conector personalizado en PowerApps. Seleccionaremos la opción Crear desde cero e introduciremos la URL de nuestra Web API (sin especificar el nombre de la función):

La pestaña Seguridad la dejaremos sin autenticación y pasaremos directamente a la parte de Definición, donde añadiremos las distintas funciones de las que dispone la API:

  • Nueva acción
  • Definir solicitud (Importar desde ejemplo)
  • Definir respuesta (Agregar respuesta predeterminada)
  • Por último, crearemos el conector y seguidamente lo probaremos

8. Crear Power App con conector personalizado

Ya disponemos de un conector con Dynamics AX 2012 funcionando correctamente, por lo que podemos proceder a la creación de una Power App en donde se utilicen las acciones definidas en dicho conector.

  • Crear origen de datos que apunte al conector
  • Crear galería que utilice la función GetCustomers

Como se observa en la imagen anterior, el propio conector ya se ha encargado de mapear el resultado JSON y ha detectado que existen dos campos, CustAccount y CustName, que podemos utilizar directamente en la galería.

Con esta pequeña prueba llegamos al final de este artículo. En siguientes partes, veremos más en detalle cómo trabajar con las funciones de la API, y cómo escribir datos en Dynamics AX desde una Power App para que la comunicación sea bidireccional.

Comparte:
Soy Miquel Vidal, ingeniero técnico en informática de sistemas, y actualmente trabajo como analista técnico y formador especializado en las soluciones empresariales de Microsoft (Office 365, Dynamics AX/365 y Power Platform).

1 comentario

  1. Xavier
    02/01/2020

    Enhorabuena por la iniciativa.

    Muy buen post y bien explicado.

    Responder

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Volver arriba