locked
CRM 2011 Plugin: Infinite loop caused by IOrganizationService.Retrieve? RRS feed

  • Question

  • I'm a bit of a loss at a particular problem I'm having with a plugin I've made. The plugin is registered on the quotedetail entity (update & pre-operation). It's supposed to calculate the values for the tax fields and enter the values in the corresponding fields. However, the plugin is causing an infinite loop. Normally this is caused by saving the entity in the plugin code it's registered on, causing the plugin to trigger itself. But the problem is I'm not saving any entity, let alone the one where the plugin is registered on. The only time I use the Organization service is to retrieve data from CRM.

    After testing this some more, I found out the infinite loop is in fact triggered the very moment the plugin calls OrganizationService.Retrieve, which fetches values from the parent quote. And sure enough, if I check the PluginExecutionContext.Depth in my code and set a return when it's more than 1, the plugin works fine. But there are times when it won't be set to 1, so I need to find out what's causing the problem. I don't understand how the Retrieve method can end up triggering a plugin. Any ideas?

    Monday, February 3, 2014 11:10 AM

All replies

  • hi, 

    have you included the fields which is updating by the plugin in the code, means are you updating those fields which are causing the on change event in plugin. for example consider you have field A and you are reading the value of A and updating this field and you have registered your field on ONchange of A.

    1. if you have included the field which is triggering the plugin, then remove that field.

     2. if this particular field is required then you need to check the depth of the context if it is more then 1or 2 you should return the plugin execution.

    IPluginExecutionContext context = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));
    IOrganizationServiceFactory factory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));
    _sdk = factory.CreateOrganizationService(context.UserId);
    ITracingService tracer = (ITracingService)serviceProvider.GetService(typeof(ITracingService));
     
    if (context.Depth > 1) { return; }


    Thanks

    Subhash 

    Monday, February 3, 2014 11:38 AM
  • hi, 

    have you included the fields which is updating by the plugin in the code, means are you updating those fields which are causing the on change event in plugin. for example consider you have field A and you are reading the value of A and updating this field and you have registered your field on ONchange of A.

    1. if you have included the field which is triggering the plugin, then remove that field.

     2. if this particular field is required then you need to check the depth of the context if it is more then 1or 2 you should return the plugin execution.

    IPluginExecutionContext context = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));
    IOrganizationServiceFactory factory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));
    _sdk = factory.CreateOrganizationService(context.UserId);
    ITracingService tracer = (ITracingService)serviceProvider.GetService(typeof(ITracingService));
     
    if (context.Depth > 1) { return; }


    Thanks

    Subhash 

    Hi,


    I'm not updating the fields that trigger the plugin. The fields that I update on quotedetail are tax and tax_base. Those are not included in the attributes that trigger the update step for the plugin. That's why I don't understand why the infinite loop is happening, since I don't even perform a direct update.The code that triggers the infinite loop is the following

    OrganizationService.Retrieve("quote", quoteId, new ColumnSet(new string[] { "pricelevelid" }));
    I don't understand how the code above can trigger a plugin, but that's what I'm seeing here.
    Monday, February 3, 2014 11:45 AM
  • Do you use a service.Update on the end of your retrieve?
    Monday, February 3, 2014 12:03 PM
  • No, I checked this several times and I only use Retrieve and RetrieveMultiple. And it's really the Retrieve itself that's causing the infinite loop, even though I don't understand why. I never call a Create or Update...
    Monday, February 3, 2014 12:24 PM
  • Are there any other plugins set to fire on Retrieve or RetrieveMultiple?
    Tuesday, February 4, 2014 4:00 PM
  • I double-checked, but no, there are no plugins registered for Retrieve or RetrieveMultiple.
    Tuesday, February 4, 2014 4:05 PM
  • I think that CRM internally applies an Update on retrieve of the Quote (and probably the Order and Invoice entities) to ensure the summed totals from the quotedetail.

    Have you specified filtering attributes on the registration on the Update message ?


    Microsoft CRM MVP - http://mscrmuk.blogspot.com/ http://www.excitation.co.uk

    Wednesday, February 5, 2014 7:14 PM
    Moderator
  • I guess the update on the quote would make sense, although in my case the Update step is registered on the quotedetail. Is there a possibility that a retrieve on Quote not only calculated the summed totals, but also (re)calculates the amount on the quotedetails before doing so? I guess that could explain what I'm seeing here. I did indeed try to limit the filtering attributes to just one attribute to try and test if this stopped the infinite loop from occurring, but with no luck. I guess I could try to check which value are actually being submitted on the target entity when in the second and following loops.
    Wednesday, February 5, 2014 7:27 PM
  • CRM may well recalcualte the quotedetail records as well. The Target InputParameter will give you all the attributes that are being updated, which may help


    Microsoft CRM MVP - http://mscrmuk.blogspot.com/ http://www.excitation.co.uk

    Thursday, February 6, 2014 2:59 PM
    Moderator