As you might know MSDyn365FO’s data access layer pretty different from T-SQL. This means that if you copy a query on AX and paste it in SSMS it won’t validate in the 99% of the cases (the other 1% being a select * from table).
Some time ago I had to create an interface between MSDyn365FO and a web service that returned data as XML. I decided to use X++’s XML classes (XmlDocument, XmlNodeList, XmlElement, etc…) to parse the XML and get the data. These classes are terrible. You get the job done but in an ugly way. There’s a better method to quickly parse XML or JSON in MSDyn365FO.
Feature management has been around in Microsoft Dynamics 365 for Finance and Operations for some time now. Before that features were enabled through flighting running a SQL query on dev and UAT boxes (and the DSE team would do it on production).
Now we have a nice workspace showing all the available features and flighting is still around too. The main difference between flighting and features is that flighting is enabled to a selected group of customers, like a preview of a feature.
If you ever need to consume a SOAP web service from Dynamics 365 for Finance and Operations, the first step you should take is asking the people responsible for that web service to create a REST version. If that’s not possible this post is for you.
I’ll use this SOAP web service I found online at http://www.dneonline.com/calculator.asmx for the example, it’s a simple service-calculator with four methods to add, substract, multiply or divide two integers.
Consuming a SOAP service in .NET
Let’s start with the basics. How do we consume a SOAP web service in Visual Studio? Easy peasy. Just add a service reference to your project:
And point it to the web service of your choice:
This will add the reference to the project:
With that done we can create an instance of the web service’s client and call one of it’s methods:
3 + 6 = 9, it looks like it’s working.
Consuming a SOAP service in Dynamics 365 for Finance and Operations
To consume the web service on FnO create a new project in Visual Studio, right click on References and add the service reference:
Hmmm… nope, it can’t be done, no service reference option.
Consuming a SOAP service in Dynamics 365 for Finance and Operations (I hope…)
The problem is that we cannot add a service reference in Visual Studio on 365 dev boxes.
What do the docs say about this? Well, like in AX2012 we need to create a .NET class library that will consume that web service, then add the reference to our DLL on 365 and call the service methods from a client object. All right!
There it is. A reference to our class library and a runnable class that will do the job:
Let’s run it!
An exception of type ‘System.
InvalidOperationException’ occurred in System.ServiceModel.dll but was not handled in user code
Additional information: Could not find default endpoint element that references contract ‘AASSOAPCalculatorService.
CalculatorSoap’ in the ServiceModel client configuration section. This might be because no configuration file was found for your application, or because no endpoint element matching this contract could be found in the client element.
Contract? What contract? I know nothing about a contract. Nobody told me about any contract! What does the Wikipedia say about SOAP?
Soap is the term for a salt of a fatty acid or for a variety of cleansing and lubricating products produced from such a substance.
Oops wrong soap…
SOAP provides the Messaging Protocol layer of a web services protocol stack for web services. It is an XML-based protocol consisting of three parts:
an envelope, which defines the message structure and how to process it
a set of encoding rules for expressing instances of application-defined datatypes
a convention for representing procedure calls and responses
The envelope is the contract. A data contract is an agreement between a service and a client that abstractly describes the data to be exchanged. That contract.
Consuming a SOAP service in Dynamics 365 for Finance and Operations (I promise this is the good one)
If we check the class library there’s a file called app.config:
In this file we can see the endpoint the DLL is using. This is fixed (hardcoded) and in case there’s a test endpoint and a production endpoint we should change the address accordingly and have two different DLLs, one for each endpoint. We can also see the data contract being used by the service, the one called AASSOAPCalculatorService.CalculatorSoap. Because #MSDyn365FO is a web-based ERP we could solve this by adding the system.serviceModel node in the web.config file of the server, right? (app.config for desktop apps, web.config for web apps). Yes, but this would be useless as we have no access to the production environment to do this, and it will be impossible to do in the sandbox Tier-2+ environments when the self-service environments start to roll out.
So, what do we do? Easy, ChannelFactory<T> to the rescue! The ChannelFactory<T> allows us to create an instance of the factory for our service contract and then creates a channel between the client and the service. The client being our class in D365and the service the endpoint (obviously).
Then we do the following:
The BasicHttpBinding object can be a BasicHttpsBinding if the web service is running on HTTPS. The endpoint is the URL of the web service. Then we instantiate a service contract from our class with the binding and enpoint and create the channel. Now we can call the web service methods and…
It’s working! And it’s even better, if there’s different endpoints for a test and prod web service we just have to parametrize them!
But really, don’t use SOAP services, go with the REST.