Tuesday, August 30, 2011

10-Minute AX 2012 App: WPF

Powerfully simple put to the test. In this first article, we will create a WPF (Windows Presentation Foundation) application, which will query AX by consuming the system services. The system services are services that provide access to the AX metadata, queries, etc. We will achieve this in 10 minutes (or less... post your time in the comments!).

Ingredients:

* Visual Studio 2010
* Access to an AX 2012 AOS


To get started, open Visual Studio 2010 and create a new project. Under C# / Windows select the "WPF Application" project type. I named this project "DAXMusings.AXWPF".



So, next up, we want to add a service reference to our AX WCF system query service. To do this, you will need to find out what address/port your AOS uses for the WSDL. On a default install, the WSDL address will be http://AOSSERVERNAME:8101/DynamicsAx/Services/QueryService . You can test this by just typing in that URL into a browser and see if you get the XML schema definition of the service (WSDL stands for Web Service Definition Language). If you don't, you can find out what the actual port number is by opening the AX 2012 Server Configuration Utility. The first tab ("Application Object Server") will show the WSDL port. Alternatively, you can open the AX client and navigate to System Administration > Setup > Services and Application Integration Framework > Inbound Ports. You won't find the QueryService in there, but if you look at one of the other services such as AxClient, it will tell you what the WSDL URL is. Just replace the "AxClient" with "QueryService".

Once you figured out your WSDL URL, go back to Visual Studio and right-click on the "References" node in your project, and select "Add Service Reference".



Enter your URL, and hit "GO". This will fetch the WSDL and show you what it has in store. Just enter a namespace (I'm using "QueryService" here, we'll use this in code so you may want to follow me on this name) and click OK.



Next, we'll add a DataGrid to the screen. In the XAML file, add one line to add the control. We'll name it "MyDataGrid" (which is pretty irrelevant for this code), and we set its ItemsSource to "{Binding}".



Lastly, we'll add some code in the MainWindow.xaml.cs which should have opened by default when you created the project. We'll add some code in the MainWindow() method.



Before I explain all that's going, and before I've passed the 10 minute mark blabbing about the details, give it a spin. If you followed to the letter and your URL is correct, you should see a data grid with all the query's fields, and whatever rows of data you have in your AX environment.

Click. What's your time? :-)



So, the AX QueryService returns a standard System.Data.DataSet .NET object. The DataGrid control has the magic. First, we set it to Binding. Notice that we didn't tell it WHAT to bind to. This is WPF feature where certain properties get passed down from parent controls to child controls (looking at the XAML file, the Window is the root, Grid is the first child, DataGrid is the child of Grid). So, from our code, we set "this.DataContext", where "this" is the window. So the Window passes down the DataContext to all its children (see this MSDN article for more information on that). DataGrid also has a property called "AutoGenerateColumns", which is set to true by default (so we don't explicitly set it in the XAML). The feature will auto generate columns for each column contained in the dataset.
Also note the "Paging" object. We use positionbased paging, which requires an explicit sort on the query. So if you try to use a different query, you may see the following error: "Paging is not supported for queries that do not have an ordering property". You can pass in a NULL reference instead of creating an instance, however, some queries return so much data it will hit the maximum buffer size of your WCF service consumer. You can change these buffer sizes in your app.config file which is contained in your project.

There's more you can do here of course. For one, you can hook up the paging object to some controls so you can actually page through the results. You could explore some of the other system services, for example to get a list of queries in the system, and then allow the user to select one and get the results.

No was that powerfully simple or what?!

11 comments:

  1. Hi Joris,

    another way to get to the Services URI is to open the AX32Serv.exe.config - File in ProgramFiles\Microsoft Dynamics AX\60\Server\..\bin.

    There are the bindings from wcf defined and you'll see a line like

    ReplyDelete
  2. Your comment cut off there at the end, but thanks, that is useful information!

    ReplyDelete
  3. Hi,

    If I'm using own web service that needs as a input an array of objects of my class (that web service brings it) - Are this able to use some kind of mapping/transform of AIF query result to this array of objects?

    PS. I'm starting with AIF so I don't have much knowledge about AIF, and maybe that what I'm asking is impossible to do :) Now I can use this web service from X++ (query result transform to array of objects) and call web service, but I don't have queue (so have to build that, but I was thinking about using AX2012 AIF queue, transforms).

    Wito

    ReplyDelete
  4. Hi Wito,

    I'm unsure of the details of what you're asking, but it seems what you want to do is perfectly possible. Please use the "contact me by email" link in the menu so we can discuss this over email a bit further.

    ReplyDelete
  5. Hi Joris,
    we have many externals applications that will need to access data on DAX.

    Reading MS "Selecting the best Development Technology..." it says that is better to use services that Strongly typed .NET interop to X++ for firewalling (RPC) reason ... what do you think?

    Thanks,
    Ivan

    ReplyDelete
  6. Check http://technet.microsoft.com/en-us/library/dd362112.aspx and search for "business connector". Microsoft does not recommend using it for new applications, and I've heard talk about it being removed in future releases of AX, although I have not found any official documentation on that. In either case, Microsoft is now using services for their own external apps (IIS/SQL reporting etc) so it's clear they don't want to use it anymore themselves.

    ReplyDelete
  7. Thanks for your answer Joris!

    With the term "business connector", you also mean the use of "Proxies" ?

    I read your examples and I find very clear ... so you suggest (as MS pointed out in the doc I was talking about) also to use Proxies only if the software runs on AOS and not on the clients?

    Ivan

    ReplyDelete
  8. With the term business connector I mean a stand alone application that that uses the business connector to connect to AX. The use of proxies doesn't have anything to do with it, really.
    I am discouraging the use of the business connector, not the use of proxies. If you absolutely have to use the business connector, you can of course use proxies to make your life easier.

    ReplyDelete
  9. Hey, im struggling with creating a infopath form to create a payment that then is posted in dynamics ax 2012.
    I understand i would have to create the whole process or order>invoice>payment

    Any hope of getting a 10min app of intergrating infopath and dynamics 2012.

    ***fingers crossed ***

    ReplyDelete
  10. Hey Joris,

    Thanks a lot for sharing this. My time though was 16 mins :) but this definitely is a veryyy useful and nicely explained article.

    Cheerss,
    Vishal

    ReplyDelete
  11. Hi All,

    How about AX 2009 Apps. Anyone know how to do it?

    Thanks in Advance,
    Ariston

    ReplyDelete