All Blog Posts - page 12
Sep 21, 2011 - Deploying your AX 2012 Code
Filed under: #daxmusings #bizappsYesterday I talked about deploying .NET assemblies, how they get automatically deployed for any Visual Studio projects you have. At the end, I talked briefly about X++ code and the CIL assemblies. I will take that a bit further today. If you haven’t read the Microsoft whitepaper on “Deploying Customization Across Microsoft Dynamics AX 2012 Environments” I suggest you take a look at that, it’s a good read.
We had a gathering with some other MCTs at Microsoft’s offices in Fargo, and we had a big discussion around deploying the customizations, and the “high availability” scenario where you want to deploy code, but avoid too much downtime. But let’s not get ahead of ourselves too quickly.
[Editing note: I admit, I like to rant. Please bear with me, I promise it will get interesting further down :-)]
I made this statement to one of our clients a few months ago, and I’d like to share it with you: moving XPOs is barbaric. Yes, barbaric. As AX developers, administrators, implementers and customers we need to move on. Yes, moving XPOs has some benefits, but they are all benefits to circumvent proper procedure. The benefit of moving one piece of code? That’s introducing risk and circumventing proper code release management (branching and merging for the version control aficionados). The benefit of no downtime? That is bad practice, what about users that have cached versions of your code running in their sessions? Not to mention data dictionary changes. The benefit of not having to recompile the whole codebase? Talk about bad practice again, and all the possible issues that come out of that. Sure, you say, but I am smart and I know what I can move without risk. Famous last words. And that’s not a reason to circumvent proper code release procedures anyway. Here’s my take:
1) Code should be released in binary form. For AX 2009 that means, layers. In AX 2012, we have models. Have you ever received a .cpp or .cs code file from Microsoft containing a patch for Windows or Office? Didn’t think so.
2) Released code should be guaranteed to be the same as the tested code (I’m sure your auditors will agree) When importing an XPO there is an overwrite and/or merge step that happens. This is prone to user error. Also, who is importing the XPO? If there is no chance of doing anything wrong or different, can’t you just have a user do it? Yeah, didn’t think so either.
3) You should schedule downtime to install code updates Sure, AX doesn’t mind a code update while that code is still running. A binary update? Not so much, you need to restart the AOS. Remember Windows asking to restart the system after an update was installed? Yes, there’s a good reason for that, to replace stuff that’s in use.
I can keep going for a while, but those are my main points. So, back to AX 2012. I will relate this to the points above.
1) Models are binary files. The .AxModel files are technically assemblies, if you open them up in Reflector or ILSpy you won’t see too much though, it contains the model manifest (XML) as a resource, and a BinaryModel resource. The model is a subset of a specific layer, so it’s a more granular way to move code than moving layers was in AX 2009. But, just like in AX 2009, since this is not the full application, after installing the model one should compile the application. An additional reason to do so in AX 2012 is the fact that the model also contains compiled X++ p-code. Any references to other classes, fields, etc gets compiled into IDs. In 2012, those IDs are installation-specific. That means your code using field ABC may have been compiled to use fieldID 1, but perhaps in the new environment you’re importing this model into, the field ABC is really fieldID 2. So now your code, when run, will reference the wrong field (you can actually test this, it’s freaky). So, compiling is a necessity. Also think of situations where your model modifies a base class. The whole application needs to be recompiled to make sure all derived classes get your update compiled into them (yes, you can do compile forward, assuming the person installing the model is aware of what is actually in the model). You can replace an existing model. This avoids the typical XPO issue where you need to import with “delete elements” enabled. Which you can’t always do since you may not want to remove other fields that are not in your XPO, but belong to another project. The model knows what it contained previously, and what it contains now, and will only delete the specific changes for your model. One thing to remember is that you should never uninstall the old model and install the new one. This will likely cause havoc in your object IDs, which means tables will get dropped and recreated rather than updated!
2) Obviously by exporting the model from an existing environment where you tested, the code will be the same. Same confidence as moving layers in previous versions of AX. Another method is moving the code using branch merging in a source environment, and creating a binary build out of that. In this case you are branching a known and tested set of code, and have full traceability of the code as it progresses through your testing and release processes.
3) Ok, this is all great, but… compiling in AX 2012 takes a LONG time compared to AX 2009. And then we need to generate the CIL as well (which doesn’t take that long in my experience)! So you catch my drift on the whole binary deployment, you see what I mean with matching released code to tested code… and starting the AOS is one thing, but having to recompile and wait for that to complete? That could be some serious downtime!
Enter.. the model store! Think about this. The model store today, is what the APPL directory used to be in previous releases. It contains EVERYTHING. The layers, which contain the code, the labels, etc. So, it contains the compiled code as well. In fact, the model store even contains the generated compiled IL code. So, going back to the “Deploying Customization Across Microsoft Dynamics AX 2012 Environments” whitepaper. It has this section called “import to the target system”. To avoid downtime, you should have a code-copy of your production environment ready, where you can replace models, do whatever you need, and then compile the application and generate the CIL for X++. This is what the whitepaper means with the “source system”. When that system is fully prepped, you can export the FULL model store. Again, this contains source code, compiled code, CIL and even your VS projects’ built assemblies! To further avoid down time, you can import the model store into production (the “target” system in the whitepaper) using a different schema. This basically lets you “import” the modelstore without disturbing the production system. Then, whenever you are ready, you can stop the AOS, and apply your temporary schema, effectively replacing the code in production with the code you built. The only thing you have to do still, after starting the AOS, is synchronize the database (and deploy web and reporting artifacts). And of course, clean up the model store’s old schema.
So, when you start up the AOS, it will recognize the changed CIL in the modelstore, and download it to its bin\vsassemblies directory (see my previous article).
Now that’s what I call high availability. So… no more reason to not move code in binary form! No more barbarism.
Sep 20, 2011 - AX 2012 .NET Assembly Deployment
Filed under: #daxmusings #bizappsCompared to AX 2009, assemblies in AX 2012 work a bit differently. One of the obvious differences is the introduction of visual studio projects. However, deploying the assemblies works differently, in our favor (of course!). There are a few things we need to keep in mind though, and definitely a few bad habits from AX 2009 to get rid of!
AX 2012 improves assembly deployment and referencing. For the client side of things, this means the assemblies no longer need to be copied to the client/bin folder. The development manuals for AX 2012 INCORRECTLY state that the assembly automatically gets downloaded by the client to the client bin folder. This is incorrect. The assemblies get downloaded to %USERPROFILE%\AppData\Local\Microsoft\Dynamics AX\VSAssemblies . The %USERPROFILE% by default on Windows 7 should be C:\Users\username so if your user name is DAXMUSINGS, the assemblies will be in C:\Users\DAXMUSINGS\AppData\Local\Microsoft\Dynamics AX\VSAssemblies . Make a correction in your 2012 development manual! Since the assemblies are kept by user, that means in a multi-user environment such as terminal services or Citrix, there is no need for all users to log out (ie all client executables closed so no more assembly files are in use) before a new assembly can be deployed. First, you don’t have to deploy, AX does it for you. Secondly, any time a user restarts AX, it will download the new assemblies where and if needed. It also means different users could have different versions of your code in use. This could happen traditionally with X++ as well, so it’s always a good idea to schedule downtime to deploy new code, managed or otherwise.
So, when you build a Visual Studio project and click “deploy” in Visual Studio (or, in fact, if you just build the project and then restart your AX client), your AX client will, the next time it needs the assembly, detect a newer version of the assembly and copy it into the VSAssemblies directory. Also note that you can in fact build the project from the AOT. When you right-click/compile on a Visual Studio project, AX builds the project and thus a new assembly.
What happens on the server side? A similar thing, except here the assemblies are deployed to the server bin/VSAssemblies . By default, the AOS runs in 1 AppDomain which means you need to restart the AOS server to get the new assembly. But, in a developer environment you may be recompiling your assembly a lot, so to avoid having to restart your AOS constantly, hotswapping was enabled for the AOS. Check this MSDN page for more information. You should definitely never enable hotswapping in a production environment!
So, for anyone who has dealt with VS projects in previous versions, please don’t copy assembly DLLs into your BIN directories. It will deploy automatically, refresh automatically, and load automatically. Also remember you don’t have to explicitly add your Visual Studio’s project as a reference in the AOT. The fact that it is an AOT VS project makes it available as an implicit reference anywhere in X++ . If you missed it previously, you may want to check out the managed code series for a look on how to create managed code projects.
Then there is the X++ compiled to IL. Those are assemblies too! Well, X++ is kept in the model store now. This includes the X++ source, the X++ p-code, and the X++ compiled IL. These compiled pieces are versioned, and the AOS will download newer versions of the X++ assemblies to it’s server bin/XppIL folder, including the PDB files so you can debug that X++ running in the CLR using Visual Studio.
Sep 16, 2011 - Windows 8
Filed under: #daxmusings #bizappsAs you may or may not have heard, this week at the build conference, the Windows 8 Developer Preview was released. You can go over to the build website, watch the keynotes (good overviews), and download the ISO files for the Windows 8 build. We’ve installed it here on a laptop, and it’s nice to see the work in progress. Stressing the work in progress. We’ve already had to reinstall it, after switching the laptop between docking station and running stand-alone, the new start screen got very confused on what monitor to be on, and decided to just disappear altogether. In any case, it’s cool to play around, it also has IE10 on it and Visual Studio Express 11, which I haven’t had time to check out yet. Make sure to watch some of the videos on the build website, they show off some good tech stuff, developing against the WinRT API using Javascript, etc.
A good friend of mine, Kevin Dockx, who is a frequent speaker on SilverLight at Microsoft events (and has written books on the subject), has put together a quick overview and his take on the whole new API, JavaScript development, etc. Check it out here. It’s a good overview for developers in case you don’t want to watch all the Build conference material.
I agree with him that the new Metro-style and start screen are great for touchscreens, but are pretty clumsy on mouse and keyboard. We have to keep in mind though that this is an early preview, so we’ll see how this ends up in the final product. For those who were involved in the AX 2012 beta program, you know how for example the sales order screen was initially redesigned (short story: it was pretty bad). Microsoft did take the beta participants’ feedback and reworked that to something way more user friendly. So let’s not scream too hard just yet, there’s a ways to go with Windows 8 development. What I like a lot is the new multi-monitor support. It’s gotten better over the years, especially with Windows 7, but I feel like the new features (taskbar per monitor, options for showing all or only windows on that monitor, etc) finally equal what other OSes and third-party plugins have offered for years now.
I’ve tried to install the AX2012 client on Windows8, but it threw an exception while checking prerequisites. I’ll try again later but at least it won’t work right out of the box (yet).
Sep 8, 2011 - AX 2012 Virtual Launch
Filed under: #daxmusings #bizappsIf you haven’t heard, this morning is the AX 2012 Virtual Launch event. Keynote from Steve Ballmer and Kirill Tatarinov followed by Gartner analyst Nigel Montgomery. Make sure to head on over to http://www.microsoft.com/dynamics/ax2012launch/ which will also allow you to replay the keynote in case you missed it!
Obviously, Microsoft is making a big deal out of this release. And rightfully so. There have been more changes in this new release than the last three releases combined! If you’ve been following my blog, you’ve noticed all the new technical features which I’ve been explaining. And I’m far from done. Of course, I only blog about technical topics, but there is just as much excitement on the functional side.
Back in the old days, before Microsoft acquired this product called ‘Axapta’, we used to not even bother “deploying” the AX client to customer’s computers. We just copied the executable and some DLLs from the install CD onto a shared folder on the network, and just gave all users a shortcut to the executable. It’s tough to put it all in words, but it’s pretty incredible how far Microsoft has brought this product. To me as a developer, who happened to land a job coding in this small but promising Danish product, it is great to see the progress, and with this 2012 release the type of investment Microsoft has made to push an already leading edge platform and take it to the next level. I’m happy to see my job is safe for quite a few years to come. I worked for VARs that also did other ERPs, and it was sad to see some great functional products getting lost in today’s technology, being bought and sold, with no roadmap or hope for an overdue technology facelift (you know who you are!).
AX has always been at the forefront of technology in the ERP world. And it’s obvious Microsoft is all-in to make sure it stays that way. I was in Fargo this week (one of the major Microsoft campuses for Dynamics) and it is clear there is a vision and a goal. Looking at the changes, both architecturally and technically, it is clear where things are going. Technologies are converging. Using C# with AX (and making X++ a managed language). Sharepoint. SQL Reporting. Office add-ins. WCF. WPF. Workflow.
These are exciting times, and I’m glad to be a part of it. Next stop - the cloud.
Sep 7, 2011 - 10-Minute AX 2012 App: Windows Azure (Cloud)
Filed under: #daxmusings #bizappsPowerfully simple put to the test. If you missed the first article, I showed you how to create a quick WPF app that reads data from AX 2012 queries and displays the results in a grid. In this article, I will continue showing you how easy it is to make use of AX 2012 technology in conjunction with other hot Microsoft technologies. Today, we will create a Windows Azure hosted web service (WCF), to which we’ll have AX 2012 publish product (item) data. Again, this will take 10 minutes of coding or less. Granted, it was a struggle to strip this one down to the basics to keep it a 10-minute project.
Windows Azure is Microsoft’s cloud services platform. We’ll be creating a web role here, hosting a WCF service. The idea I’m presenting here is an easy push of data out of AX to an Azure service. There, one could build a cloud website or web service, for example to serve mobile apps (Microsoft has an SDK to build iOS, Android and Windows Phone 7 apps based on Azure services). We’ll spend most time setting up the Azure WCF service (and a quick webpage to show what’s in the table storage), and finally we’ll create a quick AX 2012 VS project to send the data, and hook that into AX using an event handler! So, we’ll build an Azure WCF service using Table storage (as opposed to BLOB storage or SQL Azure storage). Make sure to evaluate SQL Azure if you want to take this to the next level. So, our ingredients for today will require you to install something you may not have already…
Ingredients:
- Visual Studio 2010
- Windows Azure SDK (download here)
- Access to an AX 2012 AOS
Now, the Azure SDK has some requirements of its own. I have it using my local SQL server (I did not install SQL Express) and my local IIS (I did not install IIS express).
Ok, everything installed and ready? Start the timer! You need to start Visual Studio 2010 as administrator. So right-click Visual Studio in your start menu and select “Run as Administrator”. This is needed to be able to run the Windows Azure storage emulators. We’ll start a new project and select Cloud > Windows Azure Project. I’ve named this project “DAXMusings.Azure”. Once you click OK, Visual Studio will ask you for the azure role and type of project. I’ve select “WCF Service Web Role”. Click the little button to add the role to your solution. Also, click the edit icon (which won’t appear until your mouse hovers over it) to change the name to “AXCloud”.
Ok, first things first, setup the data connection for the table storage. Right-click on the “AXCloud” under “Roles” and select properties.
Under settings, click the “Add Setting” button, name it “DataConnectionString”, set the drop down to… “Connection String”, and click the ellipsis. On that dialog screen, just select the “Use the Windows Azure storage emulator” and click OK.
Hit the save button and close the properties screen. So, what we will be storing, and communicating over the webservice, is item data. So, let’s add a new class and call it ItemData. To do this, we right-click on the AXCloud project, and select Add > New Item. On the dialog, select Class and call it “ItemData”.
So, here’s the deal. For WCF to be able to use this, we need to declare this class as a data contract. For Azure table storage to be able to use it, we need three properties: RowKey (string), Timestamp (DateTime) and PartitionKey (string). For item data, we will get an ITEMID from AX, but we’ll store it in the RowKey property since that is the unique key. We’ll just add a Name property as well, to have something more meaningful to look at. To support the data contract attribute, you’ll need to add the namespace “System.Runtime.Serialization” and for the DataServiceKey you need to add the namespace “System.Data.Services.Common”. The PartitionKey we’ll set to a fixed value of “AX” (this property has to do with scalability and where the data lives in the cloud; also, the RowKey+PartitionKey technically make up the primary key of the data…). We’ll also initialize the Timestamp to the current DateTime, and provide a constructor accepting the row and partition key.
Click here for screenshot or copy the code below:
namespace AXCloud
{
[DataContract]
[DataServiceKey(new[] { "PartitionKey", "RowKey" })]
public class ItemData
{
[DataMember]
public string RowKey { get; set; }
[DataMember]
public String Name { get; set; }
[DataMember]
public string PartitionKey { get; set; }
[DataMember]
public DateTime Timestamp { get; set; }
public ItemData()
{
PartitionKey = "AX";
Timestamp = DateTime.Now;
}
public ItemData(string partitionKey, string rowKey)
{
PartitionKey = partitionKey;
RowKey = rowKey;
}
}
}
Next, we’ll need a TableServiceContext class. We’ll need to add a reference to “System.Data.Services.Client” in our project. Just right-click on the “References” node of the AXCloud project and select “Add Reference”. On the .NET tab, find the “System.Data.Services.Client” assembly and click OK.
For easy coding, let’s add another using statement at the top as well, for the Azure storage assemblies.
And we’ll add the Context class. This will provide a property that’s Queryable, and an easy way to add an item through an AddItem() method.
Click here for screenshot or copy the code below:
public class ItemDataServiceContext : TableServiceContext
{
public ItemDataServiceContext(string baseAddress, StorageCredentials credentials)
: base(baseAddress, credentials)
{
}
public IQueryable Items
{
get
{
return this.CreateQuery("Items");
}
}
public void AddItem(string itemId, string name)
{
ItemData item = new ItemData();
item.RowKey = itemId;
item.Name = name;
this.AddObject("Items", item);
this.SaveChanges();
}
}
</code>
</pre>
So, first time we use this app (or any time you restart your storage emulator), the table needs to be created before we can use it. In a normal scenario this would not be part of your application code, but we'll just add it in here for easy measure. Open the "WebRole.cs" file in your project, which contains a method called "OnStart()". At the top, add the using statements for the Windows Azure assemblies. Inside the onstart() method, we'll add code that creates the table on the storage account if it doesn't exist.
Click here for a full screenshot or copy the below code to add before the return statement:
CloudStorageAccount.SetConfigurationSettingPublisher((configName, configSettingPublisher) =>
{
var connectionString = Microsoft.WindowsAzure.ServiceRuntime.RoleEnvironment.GetConfigurationSettingValue(configName);
configSettingPublisher(connectionString);
}
);
CloudStorageAccount storageAccount = CloudStorageAccount.FromConfigurationSetting("DataConnectionString");
storageAccount.CreateCloudTableClient().CreateTableIfNotExist("Items");
Next, we'll create a new operation on the WCF service to actually add an item. Since we already have all the ingredients, we just need to add a method to the interface and its implementation. First, in the IService.cs file, we'll add a method where the TODO is located. You probably want to remove all the standard stuff there, but to keep down the time needed and to make it easier for you to see where I'm adding code, I've left it in these screenshots.
Now, into the Service1.svc.cs we'll add the implementation of the method, for which we'll need to add the Windows Azure using statements again:
Click here for a full screenshot or copy the code below:
public void AddItem(ItemData item)
{
CloudStorageAccount.SetConfigurationSettingPublisher((configName, configSettingPublisher) =>
{
var connectionString = Microsoft.WindowsAzure.ServiceRuntime.RoleEnvironment.GetConfigurationSettingValue(configName);
configSettingPublisher(connectionString);
});
CloudStorageAccount storageAccount = CloudStorageAccount.FromConfigurationSetting("DataConnectionString");
new ItemDataServiceContext(storageAccount.TableEndpoint.ToString(), storageAccount.Credentials).AddItem(item.RowKey, item.Name);
}
So now the last thing to do is create a class the consumes this service, which we can use as a post event handler for the insert() method on the InventTable table in AX... I am skipping through some of the steps here, but basically, we create a new class library project in Visual Studio (open a second instance of Visual Studio, since we'll need to keep the Azure service running!), and "Add it to AOT". For a walkthrough on how to do this, check this blog article. We're calling this class libary "DAXMusings.ItemSubscriber".
Alright, when you have the new project created and added to the AOT, we need to add a service reference to the Azure WCF service. Since we're running all of this locally, you'll need to make sure the Azure service is started (F5 on the Azure project). This will open internet explorer to your service page (on mine it's http://127.0.0.1:81/Service1.svc). If Azure opens your web site but not the .svc file (you probably will get a 403 forbidden error then), just add "Service1.svc" behind the URL it did open. If you renamed the WCF service in the project, you'll have to use whatever name you gave it.
So, we'll add that URL as a service reference to our subscriber project, and I'm giving it namespace "AzureItems":
Now that we have the reference, we will make a static method to use as an event handler in AX. First, we need to add references to XppPrePostArgs and InventTable by opening the Application Explorer, navigating to Classes\XppPrePostArgs and Data Dictionary\Tables\InventTable respectively. For each one, right-click on the object and select "Add to project" (for more information on the why and how, check this blog post on managed handlers).
Next, there's one ugly part I will have you add. Since the reference to the service is in a class library, which will then be used in an application (AX), the service reference configuration (bindings.. the endpoint etc) which gets stored in the App.config for your class library, will not be available to the AX executables. Technically, we should copy/paste these values into the Ax32Serv.exe.config (or the client one, depending where your code will run). However, this would require a restart of the AOS server, etc. So (.NET gurus will kill me here, but just remember: this is supposed to be up and running in 10 minutes!) for the sake of moving along, we will just hardcode a quick endpoint into the code...
Click here for full screenshot of the class.
public static void InventTableInsertHandler(XppPrePostArgs args)
{
InventTable inventTable = new InventTable((Microsoft.Dynamics.AX.ManagedInterop.Record)args.getThis());
AzureItems.ItemData itemData = new AzureItems.ItemData();
itemData.RowKey = inventTable.ItemId;
itemData.Name = inventTable.NameAlias;
System.ServiceModel.BasicHttpBinding binding = new System.ServiceModel.BasicHttpBinding();
binding.Name = "BasicHttpBinding_IService1";
System.ServiceModel.EndpointAddress address = new System.ServiceModel.EndpointAddress("http://127.0.0.1:83/Service1.svc");
AzureItems.Service1Client client = new AzureItems.Service1Client(binding, address);
client.AddItem(itemData);
}
Notice how the URL is hardcoded in here (this is stuff that should go into that config file). One thing I've noticed, with the Azure project running emulated on my local machine, that it seems to change ports every now and then (I started and stopped it a few times). So you may need to tweak this while you're testing this stuff out.
So last thing to do is add this as a Post-Handler on the InventTable insert() method... (for more information and walkthrough on adding managed post-handlers on X++ objects, check this blog post)
Time to add an item and test! If you wish to debug this to see what's going on, remember the insert method will be running on the AX server tier so you need to attach the debugger to the AOS service.
How do you now know your item was actually added in the Azure table storage? Well, I will post some extra code tomorrow (a quick and dirty ASP page that lists all items in the table).
I am expecting you will run into quite a few issues trying to get through this exercise. I know I have, some of them were minor things but took me hours to figure out what I was missing. Feel free to contact me or leave a comment, and I'll try to look into each issue.
Sep 6, 2011 - New Design and New Articles
Filed under: #daxmusings #bizappsIf you haven’t noticed yet, Dynamics AX Musings has a new design. This is something I’ve been wanting to do for a while, so nothing better than a long weekend to do it. On top of that, I’ve gone through old posts and fixed all the large screenshots that were running into the right-hand menu. Going forward, rather than just a screenshot, the new design will allow me to post some code that you can copy/paste. Hopefully this will improve the usability of the articles in the future. I realize this will not show up properly in the syndication of this blog, including the syndication on community.dynamics.com but I will make sure to provide a link to the actual blog article every time. I will also still continue to provide a link to a screenshot for those who prefer that.
A link to the screenshot will go here.
public void Example()
{
info("this is an example of what it will look like");
}
On top of that, I will soon be providing downloads for all the code belonging to the big articles, including all the managed code ones, the WPF code, etc… and will continue doing that for all the future articles to come.
For those who are waiting on the continuation of the 10-minute apps for AX 2012, I will post the next one tomorrow (it’s actually finished except for the new inline code).
So thanks for being patient, and hopefully you will find that the new inline code and project downloads were worth the wait!
Sep 1, 2011 - AX 2012 Licensing
Filed under: #daxmusings #bizappsThere’s a lot of questions surrounding licensing and AX 2012, especially around user licensing. Just wanted to do a quick post and bring your attention to two blogs tackling some of these questions:
1) Becky Newell from Microsoft posted a blog article explaining the licensing and how to obtain them 2) Matrin Dráb on his Goshoom.NET DEV blog posted some more details on the licensing and useful links to partnersource and other resources
Aug 31, 2011 - 10-Minute AX 2012 App: WPF
Filed under: #daxmusings #bizappsPowerfully 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?!
Aug 30, 2011 - Three 10-minute Powerfully Simple Apps
Filed under: #daxmusings #bizappsAX 2012: Powerfully simple, you’ve probably heard that by now. We’ve looked at events, managed code, and all sorts of other interesting and powerful new things in AX 2012. Now, I’d like to show you just how powerful (and simple) some of these new things really can be. In the next few days, I will show you three apps using other hot Microsoft technologies. On top of that, these apps will only take about 10 minutes to develop from scratch (or less if you’re as good as our team…). That should fit into your 5-minute lunch break, right? You bring lunch, I’ll bring the code (-walkthrough).
Aug 23, 2011 - AX2012 Developer Resources
Filed under: #daxmusings #bizappsFor those of you who don’t visit my Dynamics AX Musings blog directly, here’s what you’ve been missing out! I have been posting quite a few lengthy articles on the subject of AX 2012, highlighting new features and actually walking through full code examples (Business Operation Framework, X++ in CLR, Events, Managed Code, Models, etc). Blogs are great, but they are horrible to navigate and don’t lend themselves well as references, since they are inherently tough to navigate. To that end, I have setup two “pages”, providing a listing of resources available, both articles on my blog as well as external resources such as MSDN articles and Whitepaper downloads. I keep these pages up-to-date any time I post a new article, so check back regularly if you’ve been missing a few posts!
The two pages available:
ALM/TFS with Dynamics AX AX 2012 Developer Resources
Blog Links
Blog Post Collections
- The LLM Blogs
- Dynamics 365 (AX7) Dev Resources
- Dynamics AX 2012 Dev Resources
- Dynamics AX 2012 ALM/TFS
Recent Posts
-
GPT4-o1 Test Results
Read more... -
Small Language Models
Read more... -
Orchestration and Function Calling
Read more... -
From Text Prediction to Action
Read more... -
The Killer App
Read more...