title: How To Write A Plugin that triggers when a related Sub-grid is updated
body: <p>I am creating a plugin that is supposed to trigger when a <strong>new record is added in a sub-grid (contractdetail) on form for the contract entity</strong>. There is a 1-N relationship between contract and contractdetail (contract_line_items). I only want my plugin to execute if the contract entity is active (statecode == 0).. I just want to update some records based on that, however, I cannot get the plugin to execute based on the criteria that I want. Here is what I have so far:</p>
  
  <pre class="lang-c# prettyprint-override"><code>using System;
  using System.Collections.Generic;
  using System.ServiceModel;
  using Microsoft.Xrm.Sdk;
  using Microsoft.Xrm.Sdk.Query;
  
  
  /// &lt;summary&gt;
  /// This plugin will update Unit Orders after the contract has already been invoiced.
  /// The update will run on the alter unit orders.
  /// &lt;/summary&gt;
  
  namespace MAGA.Plugins
  {
  
  
      [CrmPluginRegistration(MessageNameEnum.Update,
      "contractdetail",
      StageEnum.PostOperation,
      ExecutionModeEnum.Asynchronous,
      "contractid",
      "Post-Invoice Contract",
      1000,
      IsolationModeEnum.Sandbox,
      Image1Name = "PreImage",
      Image1Type = ImageTypeEnum.PreImage,
      Image1Attributes = "")]
      public class UnitPluginPostInvoice : IPlugin
      {
  
          public void Execute(IServiceProvider serviceProvider)
          {
              // Extract the tracing service for use in debugging sandboxed plug-ins.
              // Will be registering this plugin, thus will need to add tracing service related code.
  
              ITracingService tracing = (ITracingService)serviceProvider.GetService(typeof(ITracingService));
  
              //obtain execution context from service provider.
              IPluginExecutionContext context = (IPluginExecutionContext)
                  serviceProvider.GetService(typeof(IPluginExecutionContext));
  
              // InputParameters collection contains all the data passed in the message request. 
              if (context.InputParameters.Contains("Target") &amp;&amp;
                  context.InputParameters["Target"] is Entity)
              {
                  Entity entity = (Entity)context.InputParameters["Target"];
  
                  Entity PreImage = context.PreEntityImages["PreIMage"];
  
  
  
                  if (entity.LogicalName != "contractdetail" &amp;&amp; entity.GetAttributeValue&lt;OptionSetValue&gt;("statecode").Value != 0)
                      return;
  
  
                  IOrganizationServiceFactory serviceFactory =
                      (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));
  
                  IOrganizationService service = serviceFactory.CreateOrganizationService(context.UserId);
  
  
                  var contractId = entity.GetAttributeValue&lt;EntityReference&gt;("contractid");
                  var contract = service.Retrieve(contractId.LogicalName, contractId.Id, new ColumnSet(true));
  
                  if (contract.GetAttributeValue&lt;OptionSetValue&gt;("statecode").Value != 0)
                      return;
  
                  try
                  {
                      // Plugin code here
                  }
                  catch (FaultException&lt;OrganizationServiceFault&gt; ex)
                  {
                      throw new InvalidPluginExecutionException("An error occured.. Phil is responsible. ", ex);
                  }
                  catch (Exception ex)
                  {
                      tracing.Trace("An error occured: {0}", ex.ToString());
                      throw;
                  }
              }
  
  
          }
  
      }
  
  }
  </code></pre>
  
  <p>Here is a picture for a visual reference!</p>
  
  <p><a href="https://i.stack.imgur.com/gywe9.jpg" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/gywe9.jpg" alt="Contract Form"></a></p>