Stage of Execution:
Pre-Stage: (synchronous) called before the write to the database.
The main reasons to use a Pre-Stage of Execution are synchronous in nature:
- Modify data before it is written to the database.
- Abort the action being taken
- Server Side Validity checking
Post-Stage: (synchronous or asynchronous)
Use the Post-Stage of Execution whenever you don't need to use Pre-Stage.
If you don't want the user to wait for the process to finish and there is no race condition use asynchronous.
Data Images:
Pre-Image: Get the image of the record as is stored in the SQL database before the CRM Platform action has been performed
Post-Image: Returns the image of the record after the CRM Platform action has been performed
Pipeline:
Parent Pipeline: This is the pipeline that is the most common and there are no restrictions imposed in a parent pipeline.
Parent Pipeline: This is the pipeline that is the most common and there are no restrictions imposed in a parent pipeline.
Child Pipeline: This is the pipeline that causes the most confusion and there are limitations that vary with Stage and Execution Mode.
Sometimes a child pipeline is required to trap the event you need, and sometimes you need to trap both the parent and child pipeline for the same entity, message and stage
Sometimes a child pipeline is required to trap the event you need, and sometimes you need to trap both the parent and child pipeline for the same entity, message and stage
Have a look on following example for getting difference between Parent and Child Pipeline:
We can create “Quote” in following ways:
1. Sales->Quotes->New
2. Sales->Opportunity->(Open Opportunity)->Quotes->New Quote
Let us take first scenario Sales->Quotes->New
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Crm.Sdk;
using Microsoft.Crm.Sdk.Query;
using Microsoft.Crm.SdkTypeProxy;
using Microsoft.Crm.SdkTypeProxy.Metadata;
using Microsoft.Crm.Sdk.Metadata;
using System.Web.Services;
using Microsoft.Win32;
namespace TestQuotePlugin
{
public class QuotePlugin : IPlugin
{
public void Execute(IPluginExecutionContext context)
{
ICrmService crmService = (ICrmService)context.CreateCrmService(true);
IMetadataService metaData = context.CreateMetadataService(true);
lead ld = new lead();
ld.subject = "Test Subject";
ld.firstname = "Test FirstName";
ld.lastname = "Test LastName";
ld.companyname = "Test Company";
crmService.Create(ld);
}
}
}Register above plug-in as following:
Create new Quote from Sales -> Quotes -> New, then it will work and create a new Lead.
But when you create a Quote from
Sales->Opportunity->(Open Opportunity)->Quotes->New Quote then it will not work.
So you have to register a new child pipeline plug-in as following:
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Crm.Sdk;
using Microsoft.Crm.Sdk.Query;
using Microsoft.Crm.SdkTypeProxy;
using Microsoft.Crm.SdkTypeProxy.Metadata;
using Microsoft.Crm.Sdk.Metadata;
using System.Web.Services;
using Microsoft.Win32;
namespace TestQuotePlugin
{
public class QuotePlugin : IPlugin
{
public void Execute(IPluginExecutionContext context)
{
CrmService crmService = CreateCrmService(context);
lead ld = new lead();
ld.subject = "Test Subject";
ld.firstname = "Test FirstName";
ld.lastname = "Test LastName";
ld.companyname = "Test Company";
crmService.Create(ld);
}
private static CrmService CreateCrmService(IPluginExecutionContext context)
{
CrmAuthenticationToken token = new CrmAuthenticationToken();
token.AuthenticationType = AuthenticationType.AD;
token.OrganizationName = context.OrganizationName;
CrmService crmService = new CrmService();
crmService.UseDefaultCredentials = true;
crmService.Url = (string)(Registry.LocalMachine.OpenSubKey("Software\\Microsoft\\MSCRM").GetValue("ServerUrl")) + "/2007/crmservice.asmx";
crmService.CrmAuthenticationTokenValue = token;
return crmService;
}
}
}
So now when you create a Quote from
Sales->Opportunity->(Open Opportunity)->Quotes->New Quote then it will work.
Hard Coded Restrictions:
A CrmService running Synchronously in a child pipeline is limited to the following:
· Create
· Delete
· Update
· RetrieveExchangeRate
However a child plugin running in Asynchronous Execution Mode is not limited this way.
Those 4 allowed actions are hard coded by MS whenever the plugin is executed inside a transaction, and it appears that all synchronous child pipeline events occur inside a transaction.
However you can do a query in child pipeline if it is registered as asynchronous.
In review:
· Use ICrmService for all parent pipelines when at all possible.
· Use CrmService for child pipelines in asynchronous execution mode.
· There is very limited functionality allowed with CrmService for any plugin registered in a synchronous child pipeline
· Querying CRM data in a plug-in registered as a synchronous Pre Create in a child process is currently unsupported. (i.e. direct SQL access)