Wednesday, December 16, 2015

No matching MessageFilter was found for the given Message

We are calling an AIF web service from a .Net API. Everything was working and suddenly after a model store deployment, we were unable to use that service and were getting following error.

No matching MessageFilter was found for the given Message

I tried everything and could not find anything wrong. Web.config, WCF bindings everything was OK but still it would not work.

After spending couple of hours, I removed the Service References (not just update, remoed and re-added) from my code, rebuilt the API and published on IIS again and it started working.

Sunday, December 6, 2015

Sales order confirmation in batch - adding extended logic

The out of the box Sales order confirmation functionality allows us to either confirm Sales order using a click of a button (on Sales order form/list page) or we can schedule the confirmation of Sales order using a batch job (it also supports late selection query). This all works fine. However, if you want to perform additional tasks on each Sales order once it is confirmed, you will need to write some code. The class structure is something like that


Any developer familiar to inheritance would go and override the run method of SalesFormLetter_Confirmation class to perform the additional updates after the super call and it will work perfect when a Sales order is confirmed using a button. However, it will NOT work as expected when runs under a batch. It is because, batch creates multi threaded tasks and leaves them to execute later. The code written in run method of SalesFormLetter_Confirmation class would run before the Sales order is actually confirmed (under different thread) and you will not achieve your desired results as code would not be execute for SOs being confirmed under a batch.

To overcome this issue, the code must be executed when the thread actually confirms the Sales order. After performing some debugging using Visual Studio and analysing the threads I found few ways to achieve the desired results and execute the custom code for each and every Sales order under the batch right after it gets Confirmed.

  1. There is a class called "FormLetterServiceBatchTaskManager". It has run method - write your code there after the base class' run gets executed. Better check the this.ParmDocumentStatus to execute your code only for the document type you are working on. (if this.ParmDocumentStatus() == DocumentStatus::Confirmation)
  2. Write your code in method after journal gets created (Again, check the document status and execute your code only for your desired document type). 
There are some other classes which actually creates journal and they could also be considered for performing similar tasks based on your requirements.
  1. FormLetterJournalCreate (Parent class - following are few of its child classes)
  2. SalesConfirmJournalCreate
  3. SalesPickingListJournalCreate etc.

Dynamics AX Load Balancing tips

Working with Single AOS environment and Load balanced environment is very different. Specially, when it comes to releasing code in production environment or making changes in AIF service data policies. Following are few things which I learnt in my recent project:

  1. If running multiple AOSs for load balancing and you need to make data policy changes (i-e need to enable or disable fields in a web service), you must bring all AOSs down and restart the service when change is made and CIL is performed.
  2. If running multiple AOSs and made some code change that needs CIL change. Again, must bring all AOSs down and restart them when change is made to make the change effective in all environments (servers)
  3. If running multiple AOSs and modified workflow (i-e a new workflow version is added), Must refresh cache in all other environments. You don't need to bring production environment down for that purpose and just login to all servers and refresh the cache (Tools > Cache > Refresh AOD, data, dictionary)
  4. If you are using load balancing and you have written custom .net API which calls AIF services. The custom .Net API MUST be deployed on physical cluster and not the load balanced one. Otherwise, it won't be able to authenticate and you will get NTLM authentication error.

I will keep updating this post as I find and learn more.