The everyday life of a Dynamics AX developer
When trying to view or edit a workflow, the following error can pop up:
An unexpected error has occurred while opening the workflow. See the event log on the AOS and contact your system administrator to resolve the issue.
This is a general error and it could mean a lot of things. Make sure you check the obvious things first:
Well… you know… do the usual.
In my case, none of this helped. Because this was a CLR exception, I modified the try/catch in the method that was throwing the error to show the inner exception. The method Forms\WorkflowEditorHost.run was modified so it looked like this:
After trying to open the workflow again, this was the inner exception:
Kan een object van het type System.Windows.Input.CommandBinding niet converteren naar het type System.Activities.Presentation.View.DesignerView.
Cannot convert an object of type System.Windows.Input.CommandBinding to the type System.Activities.Presentation.View.DesignerView.
The fact that the error was in Dutch gave me a clue. Turn out a language pack for .NET framework 4 was installed on the machine. However, recently the .NET framework 4.5.2 was also installed on that machine. After installing the Language Pack for Microsoft .NET Framework 4.5 (link) and rebooting the machine, the error was solved.
On AX2012 FP the vendor invoice line workflow was throwing the following error which caused the workflow to stop:
Failed to create a session; confirm that the user has the proper privileges to log on to Microsoft Dynamics.
I couldn’t really figure out what was wrong, but the internet said “do a full compile and full CIL”. So I did, it didn’t help.
My colleague had a blog post about this error but that was about partitions and these are only available on R2 and R3, not on Feature Pack, so that was no help either.
After some debugging, it was clear that the error was thrown when the runAs function was executed. So I created a class and put the following method in it to test which users could not execute the runas function successfully. In this example I use the SysWorkflowDocument::assertAsUser method but it is better to create your own empty static method to test with. Remember that you have to perform an incremental CIL compilation after you have created a new static method to use in the runAs function.
This gave me a list of all users that were causing problems. Everything seemed fine with these users, so I decided to check if the SID in the UserInfo.sid field matches those on the domain for those users. I didn’t. Most likely these users were deleted on the domain and recreated with the same username, but a different SID. After the users were deleted in AX and the imported again, the error disappeared.
By the way, you can retrieve the SID of a domain user using Windows PowerShell with this command:
As a developer, I am not a big fan of database logging, but many customers and consultant love it. Most developers will probably agree that is undermines many of the performance optimizations that developers do, like using set based operations. It is no coincidence that a whole section is devoted to performance on the Configure and manage database logging page on MSDN.
But I don’t want to talk about performance now, I want to talk about the functional impact of activating database logging.
I will start with the conclusion:
Activating database logging on certain tables can change how Microsoft Dynamics AX behaves and cause hard to explain bugs. It can also cause loss of data.
To improve performance of certain processes, Microsoft Dynamics AX sometimes uses the following set-based operations:
These operations delete/update/insert multiple records in one trip to the database instead of making one call per record. Microsoft Dynamics AX does this only when the delete/update/insert methods of the table is not overwritten. For example, if you use delete_from but you have overwritten the delete() method on the table for which you are deleting records, Microsoft Dynamics AX will revert to a record by record delete instead of a set-based operation.
To counter this, you can call a number of skip* methods:
Also remember that this will only work if you are doing set-based operations, if you use the skipDeleteAction(true) method in combination with the delete() method, the delete actions will still be executed. The skip* methods are only taken into account when you use a set-based operation such as delete_from.
When you activate the database log for a certain table, all set-based operations are converted to row-based operations, as confirmed by MSDN:
When logging is enabled for a table, all database operations that would be set-based are downgraded to row-based operations. For example, if you are logging inserts for a table, each insert is performed as a row-based insert.
When we combine all of this knowledge, we realize that activating the database log on a table will cause all code that uses the skip* methods to behave differently, that is to say, the call to these methods will be ignored.
We’ve had problems with this on our project in two cases on AX 2012 FP; namely with code that deletes WMSSHipment and VendInvoiceInfoTable records in this way. In both case, because database log was active, records were being deleted that should not have been deleted. A developer can experienced the problem as for example “skipDataMethods does not work” or “skipDeleteActions does not work“. The problem of course is not the skip* methods but the database log.
If you really want to activate database logging but you have code that need to do a set-based operation, you can get around this issue by using the skipDatabaseLog method in combination with the other skip* methods.
However, in my opinion it is better not to use database log in the first place. So these are my recommendations about database logging:
— Klaas Deforche (@DynamicsAxDev) July 1, 2014
Dynamics101.com has compiled their first annual list of Top 25 Dynamics AX blogs, and this blog is in it. Some of my favorite blogs are in the list so be sure to check them out and add them to your favorites too.
When creating and using services you can get the following error:
No metadata class defined for data contract object
When you get this error it means that you are trying to use a type as a data contract that is not a valid data contract type.
Valid type are primitive types, tables and views, data contracts, containers, EDT’s, and collections (For a full list of supported types, check the Using Data Contracts in X++ [AX 2012] page on msdn.
To figure out what data member is causing a problem, put a breakpoint at the throw error in the SysOperationDataContractInfo.newParameterInfo() method. When the breakpoint is hit, the data member will be displayed in the _parentMethodParameterName variable and the type in the dictClass variable.
To solve the problem, use a type that is supported. If you want to pass a class, either pass it as a container (e.g. using a pack() method), or better yet, define the class as a data contract with data members.
Note: I’ve also seen this error pop up when the data contract wasn’t correctly compiled. Simply put a breakpoint as described above to figure out what data contract is causing the problem and compile the class (both X++ and CIL). Keep in mind that you might have to compile forward if the class is extended, or do a compile forward on the class that it extends.
I’m very happy to announce Microsoft Dynamics AX 2012 R2 Services, published by Packt Publishing and authored by Kenny and myself. It is the successor of Microsoft Dynamics AX 2012 Services which was very well received. Based on the feedback you had, we started working on an update in September 2013. We have gone through all existing content, updated and improved it, and added a lot of new content. We are really happy with the result and are excited to hear your reactions.
We are working hard on the book at the moment, the expected release date is May 2014 but you can already pre-order it.
Read on if you want to know what to expect and have a chance to win a copy of Microsoft Dynamics AX 2012 R2 Services.
We have challenged ourself to create a book that we ourself would want to read. Because of that, instead of only providing a small update, we have also added a lot of new content. To reader of the first book, it can be summarized as follows:
For new readers, we will make a chapter freely available on the Packt Publishing article network so you get a glimpse of what is in the book (I will update this page when the article is online).
To celebrate this new release, we are giving away a number of copies of the Microsoft Dynamics AX 2012 R2 Services book:
That’s 14 copies of the book and a PackLib subscription. Here’s what you need to do to win:
Announcing new book: Microsoft Dynamics AX 2012 R2 Services: http://t.co/QzkkEhSZhP Retweet to win a free copy! (See link for details)
— Klaas Deforche (@DynamicsAxDev) March 4, 2014
A big thanks to Packt Publishing for sponsoring this giveaway, and good luck to you all. The contest will close on the 21st of March 2014 and I will contact you if you win (so use your real email address when commenting).
Please check the shipping info on the website of Packt Publishing to see whether they ship to you region before entering this contest and also read their terms and conditions. Some kind of disclaimer: Keep in mind that this contest is intended to a fun experience (both for me and you). Understand that I can not make any commitments regarding the delivery of the prizes. Oh, and if I know you personally you will not win a prize :-). You can both comment and retweet by the way. Comments will have to be approved by me (so it might take some time to show up) but that’s only to avoid spam.
Good luck and I hope you like the book!
Update March 27: Contest closed, I will contact the lucky winners shortly (and update this post again).
Update: All codes have been given away, thanks for your comments!
When working with Dynamics AX, you can get the following error when opening a form:
Too many forms are currently open, close some forms and try again.
Restarting the client fixes it… for a while.
In my case the problem was that there were too many User objects in use by the Ax32.exe process. You can check how many are used in the Task Manager on the Processes tab. Click View - Select Columns… and select USER Objects from the list, then click OK. There is also a GDI Objects column that you can enable which shows a counter for a similar property (see: Object Categories).
When this is done, you should see a new column. The maximum number of allowed objects is 10000, so when the combined count reaches this point, you will get this error in AX.
When you see an application with a very high number of USER Objects, there is most likely a leak in that application. In my case ,that application was Ax32.exe. Each time I opened and closed the VendEditInvoice form, the number of USER Objects rose with more or less the number of controls on that form. After closing the form, the count didn’t drop, which it did do for other forms. This allowed me to identify that the problem was with the VendEditInvoice form.
This may have many causes, but in my case the cause was in the close method of the VendEditInvoice form. This method is overwritten but the code that was on there throws an error in some cases. A consequence of this was that super() was not executed, which caused the leak.
Conclusion: make sure you call super() on the close method of a form. When you have code that might throw an error, enclose it with a try/catch.
When activation an integration port, you can receive the following error:
The service ‘YourService’ could not be generated.\n Error: ‘YourDataContract.aMethod’ is not a valid data member
The problem is with declaration of the data member YourDataContract.aMethod. This method declaration could look like this:
As you can see, the type of the return value is Description but the type of the parameter is str. These types should be the same as shown in the following example:
Compile CIL after your made the change and redeploy your integration port, and the error should be solved.
When running setup.exe to install Microsoft Dynamics AX 2012 you can run into the following error:
autorun.hta is not a valid win32 application
As seen in the following screenshot.
In my case, the problem was due to incorrect file associations.
To correct these, go to Control Panel – Programs – Default Programs – Associate a file type or protocol with a program.
Locate the .hta extension and make sure it is associated with the Microsoft (R) HTML Application host application. You can change this by clicking the Change program… button.
The following screenshot shows the correct setup for the .hta extension.
So you need to print some files from Dynamics AX? And it also has to work in batch?
Below are 2 methods that will help you do just that.
This was the first method I used, and it works flawlessly when using text files, such as .txt or .csv files. It also works great on .prn files.
To print such a file, you can simple copy the file to the printer. See example code below.
An easy method, but do not use it on binary file types. Doing this would result in and endless stream of pages with unreadable characters on it. Yes… I’ve tried.
A better way to print files is using the System.Diagnostics namespace. This example uses the “printto” verb to print the files to the server. This verb is visible in the context menu when you right click on a file, it will be listed as the option “Print”. Basically we are using Windows this functionality together with file extension associations to automatically print any file type.
A prerequisite is that an application is available that can open and print the files you want to print. If for example you want to print PDF files in batch using this method, you should install PDF reader software on the AOS server.
You can use the code above to do many other things .The functionality is similar to shellexecute, only neater. If you are interested in modifying the code for other purposes using other verbs, you can figure out what verbs you can use using the job below. You will notice that the verbs that are available depend on the extension the file is using.
It takes a while to figure out how to do these things so hopefully this will save someone the trouble of going through that.
Hi everyone :)
I have yet to read them, but Packt Publishing was kind enough to provide me with copies for review, so expect that in the coming weeks.
At first glance, Developing SSRS reports for Dynamics AX is a great book to get you started developing SSRS reports in AX, while the reporting Cookbook will provide you with must-know receipts you will use all the time when developing. One of the receipts came in handy on the very first day I got the book, so yeah, there is value in these books.
I will do my best to get a review out as soon as possible.
Thanks a lot to Packt Publishing and especially the authors Mukesh Hirwani and Kamalakannan Elangovan for writing and publishing these books.
This guest post is written by my colleague Kristof Meesens. Thank you Kristof for contributing.
Lately I was in a deep debugging mode and used the cross references to find out some stuff.
The cross reference is a great help, but if you want to set some breakpoints it can take a lot of work.
For example you want to set a breakpoint everywhere where a field will be written.
You use the cross reference from the table/field and filter on the reference ‘write’
If you want to set a breakpoint you have to edit each line and set a breakpoint.
I created a class KrMeeSysBreakpoints that will be used to add breakpoints from a container.
The container must contain a Path, a Line number and a Boolean to enable the breakpoint.
This container will be added to another container that the class will use to loop
To use this functionality, you can add a button to the form of the cross references.
You can also call this functionality from de search form
An example screenshot from the cross references screen:
Download the XPO: SharedProject_KrMeeSetBreakpoints.xpo.
My oh my I have a secret guys, I do not like reading very much :). I want to, but I don’t. The books I bought and didn’t read, I tell you…
But I promised you a review, so I read the book and here it is. I’m exaggerating a bit though, the book is very good, so I had fun reading it.
So below is my review (the same one I posted on Amazon, where I gave it 4 stars). Keep in mind that I got a free copy of the book from Packt Publising, so that might influence my score.
As a Dynamics AX developer, you are mostly involved in the development phase of a project. When I get involved in other phases I tend to get confused about what’s going on, how stuff is decided, organized, planned, etc. If you’re a developer and you want to learn about how projects should be run like I do, than this book is exactly what you’re looking for.
That being said, I don’t think this book is really written for developers. I found it a bit hard to follow at some points, mostly because a lot of new concepts are introduced. I would need a second read-through to get it all. Luckily, this book is definitely worth that.
A lot of project managers and senior profiles would definitely benefit from reading this book. It contains a lot of do’s and don’ts that are so true. You’ll notice while ready this book saying to yourself “exactly!”. If some things are going wrong on your projects, and I bet they are, you’ll certainly be able to use this book to improve your project. Or better still, implement Sure Step completely.
The best thing about this book is that it’s about both Sure Step and Dynamics AX, so it’s all pre-processed for AX projects. You also notice that the authors are really knowledgeable on both subjects.
One thing I didn’t like is that although you are installing Sure Step client in the first chapter, it is not really used again in the rest of the book. It’s hard to know what documents are actually referred to in the book. I expected doing more with the client while reading through the book.
All in all, this is a great book and I would recommend it to everyone on the team.
When installing SSRS on a installation where the database was a backup of a customor’s setup, I got the following error:
An error occurred while adding users ‘CustomerDomain\SomeUser’,’Domain\SomeUser2′ to the SQL Server Reporting Services DynamicsAXBrowser role in the folder DynamicsAX. The error is: The user or group name ‘CustomerDomain\SomeUser’ is not recognized..
The solution was to remove all records in the SysServerSessions table.
I had to restart the AOS too for the wizard to be able to connect to the AOS again, but that could just be a glitch on my machine.
I lost some time because of this error, so thanks a lot to Paul A. Noakes for posting the solution here: