Conectar a Servicios Externos Mediante HTTPS Desde Microsoft Dynamics AX 2012
Hace ya bastante tiempo publiqué el código necesario para consumir servicios web externos desde Microsoft Dynamics AX 2012 utilizando únicamente X++. Este código se puede encontrar fácilmente en muchos sitios ya que es básicamente el mismo para casi cualquier servicio WCF, pero a veces necesitamos ajustar algunas propiedades de la conexión, por ejemplo, para conectar a extremos HTTPS.
Según la documentación de MSDN (aquí), en C# el cambio sería muy sencillo, simplemente modificando un par de propiedades del binding durante la conexión:
BasicHttpBinding b = new BasicHttpBinding(); b.Security.Mode = BasicHttpSecurityMode.Transport ; b.Security.Transport.ClientCredentialType = HttpClientCredentialType.Windows;
Sin embargo en X++, como suele pasar al utilizar tipos de .NET, la cosa no es tan simple, aunque no es demasiado complicado. Este es el código genérico que suelo usar:
protected CLRObject ServiceClient() { CLRObject serviceClient; System.String serviceUrl;
System.Type clientType;
System.ServiceModel.EndpointAddress endPointAddress;
System.ServiceModel.Description.ServiceEndpoint endPoint;
System.Exception ex;
System.ServiceModel.BasicHttpBinding binding;
System.ServiceModel.BasicHttpSecurity security;
System.ServiceModel.HttpTransportSecurity transport;
boolean isHttps;
serviceUrl = this.ServiceUrl();
isHttps = this.isHttps(serviceUrl);
try
{
clientType = CLRInterop::getType(this.ServiceTypeName());
serviceClient = AifUtil::createServiceClient(clientType);
endPointAddress = new System.ServiceModel.EndpointAddress(serviceUrl);
endPoint = serviceClient.get\_Endpoint();
endPoint.set\_Address(endPointAddress);
// Binding changes for HTTPS
if (isHttps)
{
binding = endPoint.get\_Binding();
security = binding.get\_Security();
security.set\_Mode(System.ServiceModel.BasicHttpSecurityMode::Transport);
transport = security.get\_Transport();
transport.set\_ClientCredentialType(System.ServiceModel.HttpClientCredentialType::Windows);
security.set\_Transport(transport);
binding.set\_Security(security);
endPoint.set\_Binding(binding);
}
}
catch(Exception::CLRError)
{
ex = CLRInterop::getLastException();
throw error(ex.ToString());
}
return serviceClient;
}
La configuración específica dependerá del tipo de seguridad que utilice el servicio. Este código funciona en el caso de seguridad HTTPS con autenticación delegada en la seguridad de Windows, pero el código se puede modificar fácilmente para adaptarla a otros tipos de conexión.
Espero que sea útil ;)