I will assume you have the following installed:
- Internet Information Server
- Visual Studio 2010
- Dynamics AX 2012 Client
- Dynamics AX 2012 Visual Studio Tools
First, let us create a new Project in Visual Studio. I'm want something easy and swift, so let's choose .Net 3.5 and ASP.Net Web Service Application. I'm naming the Project "PizzaSearchService" and this will automatically be part of the namespace for this application.
The project loads and you will be presented with the code for "Service1". Now just copy the code underneath and paste it in.
using System.ComponentModel; using System.Collections.Generic; using System.Web.Services; namespace PizzaSearchService { public class PizzaInfo { public string Name; public string Description; public double Prize; } [WebService(Namespace = "http://tempuri.org/")] [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)] [ToolboxItem(false)] public class Service1 : WebService { [WebMethod] public List< PizzaInfo > SearchPizza(string query) { return new List< PizzaInfo > { new PizzaInfo{ Name = "AX Beef Extreme", Description = "One of our favourites with mushroom, beef, onion and mozzarella cheese.", Prize = 12.99 }, new PizzaInfo{ Name = "AX Regular Meatlover", Description = "The good old classic with mushroom, meat, pepperoni, peppers and mozzarella cheese.", Prize = 10.99 } }; } } }
This is just a very simple service that takes a string as an input for a query for pizzas. It then returns a list of two pizzas. I love pizza, so I just couldn't help myself.
Open Internet Information Services Manager, right-click the Default Web Site and choose Manage Website and Advanced Settings...
Then click choose to select the correct Application Pool. By default IIS will have preconfigured some Applications Pools, and the one we want for now is the one named "Classic .Net AppPool", because it runs .Net 2, and our Web Service is of .Net 3.5 (built on .Net 2).
Having this set, you can head back to Visual Studio and Publish your built solution. Right-click the project and choose Publish...
Select "File System" as Publish method, and then choose a target Location.
Select Local IIS and your Default Web Site.
Now simply press Publish and your Service1.asmx and precompiled binaries will be copied to the location of your Web Site, normally under C:\inetpub\wwwroot\.
You should be able to test the Web Service by opening a browser and navigating to it. Try loading http://localhost/service1.asmx and see what happens. Unless something went horribly wrong, you should see this page listing service entry points and some extra textual description.
If you click the SearchService-link you will get a description of that service and since it takes a simple string you can invoke the service from here.
We already know the service returns the same result each time, so just press invoke and watch it open the result.
This only took you like 5-10 minutes and you're ready to consume this Web Service from within AX 2012. I recommend having a look at one of the blog posts linked above. In short, you need to do the following:
- Create a new Visual Studio Project
- Select .Net Framework 4
- Select a template from Visual C# and Windows
- Select the Class Library as template.
- Give it a name like "DynamicsAXPizzaService".
- Add a Service Reference and point to http://localhost/service1.asmx
- Add the project to the AOT
- Deploy!!
Now you are ready to consume it from within AX. You will have to restart the AX client, as already mentioned in the documentation.
In order to get you started quickly, I wrote this main-method which you can just copy and paste to test if it works.
public static void main(Args args) { DynamicsAXPizzaService.WebService1.Service1SoapClient wcfClient; DynamicsAXPizzaService.WebService1.PizzaInfo[] pizzaInfoArray; DynamicsAXPizzaService.WebService1.PizzaInfo pizzaInfo; System.ServiceModel.Description.ServiceEndpoint endPoint; System.ServiceModel.EndpointAddress endPointAddress; System.Exception ex; System.Type type; int i, numOfPizzas; str name, description, prize; ; try { type = CLRInterop::getType('DynamicsAXPizzaService.WebService1.Service1SoapClient'); wcfClient = AifUtil::createServiceClient(type); endPointAddress = new System.ServiceModel.EndpointAddress("http://localhost/service1.asmx"); endPoint = wcfClient.get_Endpoint(); endPoint.set_Address(endPointAddress); pizzaInfoArray = wcfClient.SearchPizza("mozarella"); numOfPizzas = pizzaInfoArray.get_Count(); for(i = 0; i < numOfPizzas; i++) { pizzaInfo = pizzaInfoArray.get_Item(i); name = pizzaInfo.get_Name(); description = pizzaInfo.get_Description(); prize = pizzaInfo.get_Prize(); info(strFmt("%1 - %2 - %3", name, description, prize)); } } catch(Exception::CLRError) { ex = CLRInterop::getLastException(); while(ex) { info(CLRInterop::getAnyTypeForObject(ex.ToString())); ex = ex.get_InnerException(); } } }
The output when running this class should be this:
Now that you have this working, you can start tamper with it and make it break and learn how the pieces fits together. Here are a couple of things you might want to try understand:
Now that you have this working, you can start tamper with it and make it break and learn how the pieces fits together. Here are a couple of things you might want to try understand:
- What dll is being used when the X++ code is running client side?
- Tip: have a look at this path: "%localappdata%\Local\Microsoft\Dynamics AX\VSAssemblies\"
- What dll is being used when the X++ code is running server side?
- Tip: find the location where your AOS Server files are installed and look for the VSAssemblies-folder under the bin-folder.
- What about when you activate hot-swapping of assemblies on the AOS?
- What happens if you deploy new versions of these dlls and you want the client or the AOS to load this new version?
- Either restart the client or restart the AOS, depending on what dll you want reloaded.
- What if you plan to have the dll run only server side and never client side, but you need intellisense while developing the X++ code?
- You need the dll deployed client side on the developer machine. :-)
Finally, I wanted to show you a neat little tool by JetBrains named dotPeek. If you take any of the dlls you just created and drop them into this tool, you can explore the content and even browse the code. I have used this tool in many different scenarios to peek inside managed assemblies.
If you have any concerns or you bump into any issues while trying to follow the steps in this article, please leave a comment underneath.
If you have any concerns or you bump into any issues while trying to follow the steps in this article, please leave a comment underneath.