Thursday, August 25, 2011

Dynamics CRM 2011 : Registering CRM 4.0 Plugin in CRM 2011 Deployment


The backward compatibility in Dynamics CRM 2011 for Dynamics CRM 4.0 supports CRM 4.0 web services end points and allows to register CRM 4.0 plugins, workflow assemblies, develop code for Web services Jscript or ASP.Net code. In many scenarios the pervious written code for CRM 4.0 works fine in CRM 2011. While browsing Microsoft Dynamics CRM Forums, i found many posts regarding the registration of CRM 4.0 plugin in CRM 2011 so I decided to post the complete steps by step solution with the plugin registration tool updated files.
*The solution describes below has been based on the findings of Microsoft Dynamics CRM MVP David Jennaway.
Dynamics CRM 4.0 Plugin Registration in CRM 2011:
You can download the Updated Registration Tool Exe Files (CRM 4.0 Plugin Registration Tool Exe Files.zip) or CRM 4.0 plugin registration updated Visual Studio 2010 solution (CRM 4.0 Plugin Registration Tool Exe Files.zip) or may also follow the steps below to make required changes into the CRM 4.0 Plugin Registration Tool Configuration file.
CRM 4.0 plugins can be registered via Dynamics CRM 4.0 plugin registration tools and if you will register a CRM 4.0 plugin via CRM 2011 plugin registration tool then following error will occur:
Error 
Unhandled Exception: System.IO.FileNotFoundException: Could not load file or assembly 'Microsoft.Crm.Sdk, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' or one of its dependencies. The system cannot find the file specified
Solution Steps:


You can download the solution file from the above links but if you want to make manually changes into the CRM 4.0 plugin Registration configuration file then follow the steps below:
1. Open Dynamics CRM 4.0 Plugin Registration tool Source code into Visual Studio (you can find the source code into the CRM 4.0 SDK\Tools\Plugin Registration Tool directory)
2. Edit app.config file and add the runtime information below:


<configuration>
        <configSections>
                <sectionGroup name="applicationSettings"
         type="System.Configuration.ApplicationSettingsGroup, System, Version=2.0.0.0,
                        Culture=neutral, PublicKeyToken=b77a5c561934e089">
                        <section name="PluginRegistrationTool.Properties.Settings"
                     type="System.Configuration.ClientSettingsSection, System,
                               Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
                     requirePermission="false"/>
                </sectionGroup>
        </configSections>
        <startup>
                <supportedRuntime version="v2.0.50727"/>
        </startup>

       
       <!--The following <runtime> information will be added-->

        <runtime>
                <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
                        <dependentAssembly>
                                <assemblyIdentity name="Microsoft.Crm.Sdk" publicKeyToken="31bf3856ad364e35"
                                 culture="neutral"/>"
                                <publisherPolicy apply="no"/>
                        </dependentAssembly>
                </assemblyBinding>
        </runtime>
</configuration>


3. Build and run the plugin registration tool, enter CRM 2011 server connectivity details and register the CRM 4.0 plugins into CRM 2011
*If you have the Plugin Registration Tools executable binaries then you edit the PluginRegistration.exe.config file instead of app.config.

Wednesday, August 24, 2011

Dynamics CRM 2011 : Opportunity Plugin Update Message Trigger on Opportunity Record Creation


On creating opportunity record if plugin is registered for Update event then it will automatically trigger and the code written for the Update event will be executed, to prevent from this erroneously behavior you can add a condition to check if plugin parent Context execution message is null then execute the code.

 [Plugin: C# Code]


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.Metadata;
using Microsoft.Crm.Sdk;

namespace wod.Crm.PluginDebugger
{
    public class wodPlugin : IPlugin
    {
        public void Execute(IServiceProvider serviceProvider)
        {
            // Obtain the execution context from the service provider.
            IPluginExecutionContext context = 
            (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));

            // check if parenet context message is Create and current contetx message is Update then return 
            //and does not execute code.
            if (context.MessageName == "Update" && context.ParentContext != null && 
                context.ParentContext.MessageName == "Create")
            {
                return;
            }
            else
            {
                // Write your update Opportunity record code here
            }

        }
    }
}



Monday, August 22, 2011

Dynamics CRM 2011 : Execute Custom Business Logic in Plugin on Incomming Email Tracking


Sometime there is a requirement to execute custom code for performing custom validations, extract data or manipulate data on receiving incoming email in Microsoft Dynamics CRM 2011. The following step by step guide steps explains to develop and register a CRM SDK plugin to achieve this functionality.
[Instructions]

1. Use the plugin code below or download the plugin solution wod.Crm.IncommingEmail, make required changes and build plugin assembly file.
2. Use plugin registration tool to register the plugin assembly and then register a new plugin step for Email entity on Create event with Pre-Operation event pipeline stage in Synchronous execution mode

[Plugin: C# Code]


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.Metadata;
using Microsoft.Xrm.Sdk.Query;
using Microsoft.Crm.Sdk;

namespace wod.Crm.IncommingEmail
{
    public class wodPlugin : IPlugin
    {
        public void Execute(IServiceProvider serviceProvider)
        {
            // Obtain the execution context from the service provider.
            Microsoft.Xrm.Sdk.IPluginExecutionContext context = (Microsoft.Xrm.Sdk.IPluginExecutionContext)
                serviceProvider.GetService(typeof(Microsoft.Xrm.Sdk.IPluginExecutionContext));

            IOrganizationServiceFactory wod_serviceFactory = null;

            IOrganizationService wod_CrmService = null;

            try
            {
                wod_serviceFactory = (IOrganizationServiceFactory)serviceProvider.GetService(
                         typeof(IOrganizationServiceFactory));
                wod_CrmService = wod_serviceFactory.CreateOrganizationService(context.UserId);

                if (context.MessageName == "Create" &&
                    context.InputParameters.Contains("Target") &&
                    context.InputParameters["Target"] is Entity
                    )
                {
                    Entity wod_PluginEntity = (Entity)context.InputParameters["Target"];

                    //Checking if plugin is trigger for Email entity
                    if (wod_PluginEntity.LogicalName == "email")
                    {
                        // Checking if email direction is incomming
                        if (wod_PluginEntity.Contains("directioncode"))
                        {
                            // Checking if email is incomming
                            if (((Boolean)wod_PluginEntity["directioncode"]) == false)
                            {
                                EntityCollection wod_IncommingParty = null;

                                wod_IncommingParty = (EntityCollection)wod_PluginEntity["from"];

                                // Checking if plugin entity From field is activityparty entity object

                                if (wod_IncommingParty != null && wod_IncommingParty[0].LogicalName
                                 == "activityparty")
                                {
                                    EntityReference wod_PartyReference =
                                    (EntityReference)wod_IncommingParty[0]["partyid"];

                                    // Checking if email is sent by CRM Account
                                    if (wod_PartyReference.LogicalName == "account")
                                    {
                                        // Retrieve sender Account record
                                        Entity wod_Account = wod_CrmService.Retrieve("account",
                                        wod_PartyReference.Id, new ColumnSet(true));

                                        // You can write your code for validation, data manipulation here
                                        throw new Exception("email account: " + wod_Account["name"]);

                                    }
                                }
                            }
                        }
                    }
                }
            }

            catch (System.Web.Services.Protocols.SoapException ex)
            {
                throw new InvalidPluginExecutionException(ex.Detail.InnerText);
            }
            catch (Exception ex)
            {
                throw new InvalidPluginExecutionException(ex.Message);
            }
        }
    }
}