Friday, July 10, 2009

Plugin for copying notes and attachements from lead to contact whis is converted from lead for Microsoft Dynamics CRM 4.0

I've been asked to write plugin for following scenario:
When user converts lead to contact - all attachements and notes must be copied to retrieved contact.

Code of the plugin:

using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Crm.Sdk;
using Microsoft.Crm.SdkTypeProxy;
using Microsoft.Crm.Sdk.Query;

namespace LeadConversionPlugin
public class ContactCreationHandler : IPlugin
#region IPlugin Members

public void Execute(IPluginExecutionContext context)
if (context.MessageName == MessageName.Create &&
context.InputParameters.Contains("Target") &&
context.InputParameters["Target"] is DynamicEntity)
DynamicEntity entity = (DynamicEntity)context.InputParameters["Target"];

//Check that target entity is contact
if (entity.Name !=

//Check that this contact is created in the way of
//convertion from lead
if (!entity.Properties.Contains("originatingleadid"))

//Source Lead Identifier
Guid leadid = ((Lookup)entity["originatingleadid"]).Value;

//Target Contact Identifier
Guid contactid = (Guid)context.OutputParameters["Id"];

ICrmService crmservice = context.CreateCrmService(true);

//Just build the query which will be used to retrieve
//all child annotations (notes and attachements)
QueryByAttribute query = new QueryByAttribute();
query.ColumnSet = new AllColumns();
query.EntityName = EntityName.annotation.ToString();

query.Attributes = new string[] { "objectid" };
query.Values = new object[] { leadid };

RetrieveMultipleRequest request = new RetrieveMultipleRequest();
request.Query = query;
request.ReturnDynamicEntities = false;

RetrieveMultipleResponse response = (RetrieveMultipleResponse)crmservice.Execute(request);

foreach (annotation note in response.BusinessEntityCollection.BusinessEntities)
//Just remove Key field of annotation
note.annotationid = null;

//Replace referencing object lookup with newly created contact lookup
note.objectid = new Lookup(, contactid);
note.objecttypecode = new EntityNameReference(;

//And Create the annotation record

#endregion IPlugin Members

Step for this plugin must be registered as a Post Create Syncronous Parent Pipeline.


  1. Hi Andrij,
    Thank you for excellent example and openness, it works!

  2. Hi I am also trying to use the same code for CRM 2011. Just difference is that I have used linq rather than query. I am able to retrieve the notes but when I am trying to generate the note for account entity, I am getting the below error :-

    EntityState must be set to null, Created (for Create message) or Changed (for Update message)

    Any idea how can I resolve this?

    1. 1. I don't see your code.
      2. Use debugger and google.