Monday, June 1, 2015

Microsoft Dynamics AX 2012 Class Libraries (DLLs)

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
 
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <startup>
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
    </startup>
    <system.serviceModel>
        <bindings>
            <netTcpBinding>
                <binding name="NetTcpBinding_AdvancedLedgerEntryService" />
            </netTcpBinding>
        </bindings>
        <client>
            <endpoint address="net.tcp://ax2012r2a:8201/DynamicsAx/Services/AlexServices"
binding="netTcpBinding" bindingConfiguration="NetTcpBinding_AdvancedLedgerEntryService"
contract="ServiceReference1.AdvancedLedgerEntryService" name="NetTcpBinding_AdvancedLedgerEntryService">
                <identity>
                    <userPrincipalName value="admin@Contoso.com" />
                </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
 
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <system.serviceModel>
        <bindings>
            <netTcpBinding>
                <binding name="NetTcpBinding_AdvancedLedgerEntryService" />
            </netTcpBinding>
        </bindings>
        <client>
            <endpoint address="net.tcp://ax2012r2a:8201/DynamicsAx/Services/AlexServices"
binding="netTcpBinding" bindingConfiguration="NetTcpBinding_AdvancedLedgerEntryService"
contract="ServiceReference1.AdvancedLedgerEntryService" name="NetTcpBinding_AdvancedLedgerEntryService">
                <identity>
                    <userPrincipalName value="admin@Contoso.com" />
                </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
 
<?xml version="1.0"?>
<configuration>
    <system.serviceModel>
        <bindings>
            <netTcpBinding>
                <binding name="NetTcpBinding_AlexService" />
            </netTcpBinding>
        </bindings>
        <client>
            <endpoint address="net.tcp://ax2012r2a:8201/DynamicsAx/Services/AlexServices"
                binding="netTcpBinding" bindingConfiguration="NetTcpBinding_AlexService"
                contract="AXServiceReference.AlexService" name="NetTcpBinding_AlexService">
                <identity>
                    <userPrincipalName value="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 = new BasicHttpBinding();
binding.Security.Mode = BasicHttpSecurityMode.TransportCredentialOnly;
binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Windows;
 
EndpointAddress address = new EndpointAddress("http://ax2012r2a.contoso.com/MicrosoftDynamicsAXAif60/AlexWebServices/xppservice.svc");
 
AlexServiceClient client = new AlexServiceClient(binding, address);
 
CallContext context = new CallContext();
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
{
    public class Class1
    {
        public string 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
 
static void 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