- Create a new solution in CRM2011. I named my solution “CRM Plugin Solution”.
- Open Visual Studio 2010. Select File—New –Project. It will display new project templates dialog as shown in the screen sheet below
- Select “Dynamics CRM 2011 Package” project. This is also optional. You can go ahead and select “Dynamics CRM 2011 Plugin Library”, but then you cannot deploy the plugin straight from the Visual Studio. You have to use Plugin Registration tool to register the plugin. Enter the name of project/solution.
- VS studio will display following dialog. Enter you CRM 2011 server details. Select the solution name we created in step 1 and click ok
- Now right click on the solution and add “Dynamics CRM 2011 Plugin Library” project to the solution. The plugin project will already have a plugin.cs file.
- Now sign the plugin assembly. Right click on Plugin Project and select properties. Select Signing tab from left navigation of project property page. On the Signing tab, select the Sign the assembly check box and set the strong name key file of your choice. At a minimum, you must specify a new key file name. Do not protect your key file by using a password.
- If you cannot see the “CRM Explorer” window on the upper left side of the VS studio, click on View menu and select “CRM Explorer”.
- Now expand “Entities” Node. Right Click on “Account” entity and select “Create Plugin”.
- It will display a following screen. It is equivalent to “Update Step” screen in plugin registration tool. Notice the “Pre Image Alias” and “Post Image Alias”. I have passed the “telephone1” attribute to the pre image and post image. You can change of the Class attribute. Press Ok.
- It will create a PostAccountUpdateContacts.cs file with name mentioned in “Class” attribute in screen shot above. Double click on the class file (PostAccountUpdateContacts.cs).
- Add the following references at the top
- Scroll down the PostAccountUpdateContacts.cs file and look for ExecutePostAccountUpdateContacts method. Overwrite the method with the following code. Look at the comments to understand the code
- Now right click on CRM Package project we created in step 2 and select deploy. It will register the plugin assembly as well as step, preEntityImage and postEntityImage for the plugin.
- Update the “Main Phone” on account entity and test the plugin.
using Microsoft.Xrm.Sdk.Client; // to get the OrganizationContext using System.Linq; // to use linq queries with OrganizationContext
protected void ExecutePostAccountUpdateContacts(LocalPluginContext localContext)
{
if (localContext == null)
{
throw new ArgumentNullException("localContext");
}
string oldPhone = ""; // to store the old Main Phone no:
string newPhone = ""; //// to store the new Main Phone no:
// get the plugin context
IPluginExecutionContext context = localContext.PluginExecutionContext;
//Get the IOrganizationService
IOrganizationService service = localContext.OrganizationService;
//create the service context
var ServiceContext = new OrganizationServiceContext(service);
ITracingService tracingService = localContext.TracingService;
// The InputParameters collection contains all the data passed in the message request.
if (context.InputParameters.Contains("Target") &&
context.InputParameters["Target"] is Entity)
{
// Obtain the target entity from the input parmameters.
Entity entity = (Entity)context.InputParameters["Target"];
// get the pre entity image
Entity preImageEntity = (context.PreEntityImages != null && context.PreEntityImages.Contains(this.preImageAlias)) ? context.PreEntityImages[this.preImageAlias] : null;
// get the post entity image
Entity postImageEntity = (context.PostEntityImages != null && context.PostEntityImages.Contains(this.postImageAlias)) ? context.PostEntityImages[this.postImageAlias] : null;
// get the preimage and postimage telephone1 value
if (preImageEntity.Attributes.Contains("telephone1"))
{
oldPhone = (string)preImageEntity.Attributes["telephone1"];
}
if (postImageEntity.Attributes.Contains("telephone1"))
{
newPhone = (string)postImageEntity.Attributes["telephone1"];
}
if (newPhone != oldPhone)
{
try
{
//Create query to get the related contacts
var res = from c in ServiceContext.CreateQuery("contact")
where c["parentcustomerid"].Equals(entity.Id)
select c;
foreach (var c in res)
{
Entity e = (Entity)c;
e["telephone1"] = newPhone;
//ServiceContext.Attach(e);
ServiceContext.UpdateObject(e);
}
ServiceContext.SaveChanges();
}
catch (FaultException ex)
{
throw new InvalidPluginExecutionException("An error occurred in the plug-in.", ex);
}
}
}
}
Great...
ReplyDeleteI am having a problem. When I update the phone number in the Main account entity, it updates a the phone number in contact entity with previous data. Ex. if old data was 222555 and I changed it to 000000, it will update contact entity's phone number with 222555. I followed all the steps along with sync plugin and Post Operation.
ReplyDeleteHave a look, you may be using the preimage value instead of postimage value.
DeleteThe field name for my preimage value and postimage value are same. Could that be the reason? 'telephone1' field in your example is also the same. Does it make sense?
DeleteSolved. I was saving newvalue in preimage entity and hence the issue. Thanks for your help!
DeleteGood stuff.
DeleteBtw, thanks for awesome stuff!
DeleteI followed your instructions except I'm running the my plugin from the contact entity.
ReplyDeleteWhen a contact record is updated, the plugin will update other contacts which have the same email as the one that was initially updated. I have my code set up just like yours except for the query and my variables/fields I'm using.
After I deploy and try to update a contact record, the other contact records are not being updated.
Any ideas what could be wrong?
Thanks