Microsoft Dynamics AX 2012 Class Libraries (DLLs)
Purpose: The purpose of this document is to illustrate how to work with class libraries in the context of Microsoft Dynamics AX 2012.
Challenge: For the purposes of POC, integration project or development project you may need to consume Microsoft Dynamics AX 2012 Web Services from external class libraries or call external Web Services from Microsoft Dynamics AX 2012 managed code assemblies.
Solution: In this walkthrough I'm going to highlight number of ways you can consume Microsoft Dynamics AX 2012 Web Services from external class library using configuration settings in application config file or handled in the application code. Also I will highlight how develop Microsoft Dynamics AX 2012 managed code assemblies and then call external Web Services from there.
Walkthrough
Calling Microsoft Dynamics AX 2012 Web Service from external Class Library (DLL)
First of all I will expose Microsoft Dynamics AX 2012 Web Services via Inbound ports using NET.TCP and HTTP adapters
Inbound port (NET.TCP)
Inbound port (HTTP)
IIS
After Web Services have been exposed through Inbound ports in your client application you can Add Service Reference using WSDL URI as shown below
Add Service Reference (NET.TCP)
Add Service Reference (HTTP)
Added Service Reference will show up in your project as below
Solution Explorer (Console App)
Please note that corresponding Endpoint and Binding details will be added to App.config after you added Service Reference
App.config
<?xmlversion="1.0"encoding="utf-8" ?> <configuration> <startup> <supportedRuntimeversion="v4.0"sku=".NETFramework,Version=v4.5" /> </startup> <system.serviceModel> <bindings> <netTcpBinding> <bindingname="NetTcpBinding_AdvancedLedgerEntryService" /> </netTcpBinding> </bindings> <client> <endpointaddress="net.tcp://ax2012r2a:8201/DynamicsAx/Services/AlexServices" binding="netTcpBinding"bindingConfiguration="NetTcpBinding_AdvancedLedgerEntryService" contract="ServiceReference1.AdvancedLedgerEntryService"name="NetTcpBinding_AdvancedLedgerEntryService"> <identity> </identity> </endpoint> </client> </system.serviceModel> </configuration> |
Now I’ll create a class library project and Add Service Reference too
Solution Explorer (Class Library)
Similarly to above corresponding Endpoint and Binding details will be added to App.config
App.config
<?xmlversion="1.0"encoding="utf-8" ?> <configuration> <system.serviceModel> <bindings> <netTcpBinding> <bindingname="NetTcpBinding_AdvancedLedgerEntryService" /> </netTcpBinding> </bindings> <client> <endpointaddress="net.tcp://ax2012r2a:8201/DynamicsAx/Services/AlexServices" binding="netTcpBinding"bindingConfiguration="NetTcpBinding_AdvancedLedgerEntryService" contract="ServiceReference1.AdvancedLedgerEntryService"name="NetTcpBinding_AdvancedLedgerEntryService"> <identity> </identity> </endpoint> </client> </system.serviceModel> </configuration> |
In fact when leveraging business logic from class library you have to use client application config file instead of original DLL config file. That’s why I will copy Endpoint and Binding details from DLL config file over to client app config file
Client application Config file
<?xmlversion="1.0"?> <configuration> <system.serviceModel> <bindings> <netTcpBinding> <bindingname="NetTcpBinding_AlexService" /> </netTcpBinding> </bindings> <client> <endpointaddress="net.tcp://ax2012r2a:8201/DynamicsAx/Services/AlexServices" binding="netTcpBinding"bindingConfiguration="NetTcpBinding_AlexService" contract="AXServiceReference.AlexService"name="NetTcpBinding_AlexService"> <identity> <userPrincipalNamevalue="admin@Contoso.com" /> </identity> </endpoint> </client> </system.serviceModel> </configuration> |
Now my client application will be well aware about Endpoint and Binding details for Microsoft Dynamics AX 2012 Web Service
Alternatively you can handle Endpoint and Binding details for Microsoft Dynamics AX 2012 Web Service directly in client application code as shown below
Client application Code
BasicHttpBinding binding = newBasicHttpBinding(); binding.Security.Mode = BasicHttpSecurityMode.TransportCredentialOnly; binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Windows; EndpointAddress address = newEndpointAddress("http://ax2012r2a.contoso.com/MicrosoftDynamicsAXAif60/AlexWebServices/xppservice.svc"); AlexServiceClient client = newAlexServiceClient(binding, address); CallContext context = newCallContext(); context.Company = "usmf"; client.ClientCredentials.Windows.ClientCredential.Domain = "contoso"; client.ClientCredentials.Windows.ClientCredential.UserName = "Admin"; client.ClientCredentials.Windows.ClientCredential.Password = "pass@word1"; try { client.method1(context); } catch (Exception e) { } |
Call external Web Service from Microsoft Dynamics AX 2012 Class Library (DLL)
In the second part of the walkthrough I’m going to wrap a business logic calling external Web Service with Microsoft Dynamics AX 2012 managed code assembly
First off I’ll create Class Library project with minimalistic implementation for a single class and method which mimic calling external Web Service
Class Library
As coding is complete I’ll add Class Library project directly into Microsoft Dynamics AX 2012 AOT. Please note that I have Microsoft Dynamics AX 2012 Visual Studio Tools installed to accomplish this: https://technet.microsoft.com/en-us/library/dd309576.aspx
My project now will change its icon to Microsoft Dynamics specific one, after that I’ll be able to select auto-deployment options in Project Properties. Specifically I will choose to deploy assembly to Microsoft Dynamics AX 2012 Client (Yes) and Server (Yes)
Class Library (Deployment)
After successful deployment my project will show up in Microsoft Dynamics AX 2012 AOT
AOT – C Sharp Projects
Here’s the implementation of class and method which mimic calling external Web Service from within Microsoft Dynamics AX 2012 managed code assembly
Source code
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace AlexDLL { publicclassClass1 { publicstring method1() { return"External Web Service call"; } } } |
Generally it would be a good idea to encapsulate business logic calling external Web Service in a single method in managed code assembly, this way you can simply call a single method in X++ to consume Web Service and obtain the result
When deploying assemblies from within Visual Studio you may need to make sure that “Enable the hot-swapping of assemblies for each development session” setting is selected in Microsoft Dynamics AX 2012 Server Configuration Utility in order to avoid deployment errors
Microsoft Dynamics AX 2012 Server Configuration Utility
Before you deploy you will need to Sign the assembly in Project Properties > Signing
Create Strong Name Key
Now we are ready to deploy the assembly
Deploy
Upon successful deployment you will be able to use IntelliSense in X++ and consume elements of managed code assembly namespace just the way you consume native X++ business logic classes
X++ code
staticvoid DLL(Args _args) { AlexDLL.Class1 class1 = new AlexDLL.Class1(); info(class1.method1()); } |
The result will look like below
Result
Please learn more about Deploying Managed Code Assemblies here: https://msdn.microsoft.com/en-us/library/gg889192.aspx
Summary: In this walkthrough I illustrated how to call Microsoft Dynamics AX 2012 SOAP Web Services from Windows 8 application using JavaScript and shed some light into what's happening behind the scenes when you call Web Service, how request and response look like and what you have to do to successfully call Microsoft Dynamics AX 2012 SOAP-based Web Services.
Tags: Microsoft Dynamics AX 2012, Custom Web Services, X++, C#.NET, HTTP, NET.TCP, Config file, Class library, DLL, Endpoint, Binding.
Note: This document is intended for information purposes only, presented as it is with no warranties from the author. This document may be updated with more content to better outline the issues and describe the solutions.
Author:Alex Anikiev, PhD, MCP