Monday, December 27, 2021

Plugin in Dynamic 365 CRM


In this blog, we will get an overview of a plugin with a detailed step-by-step creation of a plugin with an example. 

Here, we will create a plugin that will trigger when the Lead is created and will create a follow-up task.

Connect to Dynamic 365 CRM from Console App using Azure Authentication

Why Plugin?

Plugins are custom code that attaches to CRM’s built-in event pipeline. This allows developers to extend the default behavior of CRM so we could design/develop it exactly as per the organizational needs.


Create a .NET project:

From Visual Studio, create a new Project. Add Class Library (.net Framework). Click on Next.


Now, give a relevant name for the project. Click on Create. This will create a new project with a class.



Right-click on the Project. Then click on Manage NuGet Package. Add the Microsoft.CrmSdk package. Click on Install.


Add the below Plugin Code:


using System;

using Microsoft.Xrm.Sdk;

 

namespace FollowupTaskPlugin

{

    public class Class1 : IPlugin

    {

        public void Execute(IServiceProvider serviceProvider)

        {

                // Obtain the execution context from the service provider.

                IPluginExecutionContext context = (IPluginExecutionContext)

                   serviceProvider.GetService(typeof(IPluginExecutionContext));

     

         if (context.InputParameters.Contains("Target") && context.InputParameters["Target"]is Entity) {

 

                    // Obtain the target entity from the input parameters.

                    Entity entity = (Entity)context.InputParameters["Target"];

                    try

                    {

 

                        // Create a task activity to follow up with the account customer in 7 days

                        Entity followup = new Entity("task");

                        followup["subject"] = "Send e-mail to the new User";

                        followup["description"] ="Follow up with the User";

                        followup["scheduledstart"] = DateTime.Now;

                        followup["scheduledend"] = DateTime.Now.AddDays(2);

                        followup["category"] = context.PrimaryEntityName;

 

                        if (context.OutputParameters.Contains("id"))

                        {

                            Guid regardingobjectid = new Guid(context.OutputParameters["id"].ToString());

                            string regardingobjectidType = "lead";

                            followup["regardingobjectid"] =

                               new EntityReference(regardingobjectidType, regardingobjectid);

                        }

 

                        IOrganizationServiceFactory serviceFactory =

                           (IOrganizationServiceFactory)serviceProvider.GetService

                           (typeof(IOrganizationServiceFactory));

                        IOrganizationService service =

                           serviceFactory.CreateOrganizationService(context.UserId);

 

                        service.Create(followup);

                    }

                    catch (Exception ex)

                    {

                        throw new InvalidPluginExecutionException(ex.Message);

                    }

                }

            }

        }

    }


Step 2: Signing the assembly:

Before Registering for the assembly, we need to sign in.

  • Right-click on the project, choose Properties.
  • Choose the Signing option.
  • Select the Sign the assembly box.
  • In the Choose a strong name key file box, choose Browse/new, and then navigate to the key file.
  • You may uncheck the Key to avoid password Authentication.




Signing an assembly ensures that the consumer knows its origin and uniquely identifies the component. It makes the physical DLL file tamper-proof.

A very important reason to sign an assembly is so you can be sure it is your assembly.

If we put the private key, others cannot sign an assembly with that same key.

Signing your dll makes the most sense when you verify those signatures before loading them. This ensures the integrity of all dll at runtime. It is a recommended security practice to sign all binaries that you ship and validate their signatures at runtime.

If we do not sign in to the assembly, we will get the below error:



Right Click on the Solution and build the Solution.

Step 3: Register the Plugin. Go to the Plugin registration tool.

Click on Create connection and then check the Display list of available Organizations. Click on login.


It will now retrieve the Organization you have logged in to. Enter the Organization credentials.


Click on Register >Register New Assembly.



Select the DLL file from the folder and add the register.


Load the assembly and now, click on Register and then Select Register new Step.


Since we are creating a follow-up task on the creation of lead, hence we will select the following:  

Message: Create

Primary Entity: Lead

Event Pipeline: Post Operation

Execution Mode: Synchronous.


Click on Register new Step.

Now, check the operation from Dynamics CRM. A follow-up task should be created on the creation of a lead record.




Synchronous and Asynchronous:

 

Synchronous plugins are triggered straight away.  So, if your plugin is triggered on the Create message, it will run directly either on post-operation or pre-operation. The CRM form will wait until the Synchronous plugin has finished processing before the form reloads. Can run on both post-operation and pre-operation. This will run only for 2 minutes and blocks users until completed.

 

Asynchronous plugins will be triggered sometime later when the CRM service has enough resources. We cannot assume when this will be triggered.  Async plugins do not slow the form reloading because it doesn’t have to wait. This will run only for 2 minutes and does not block users from seeing the operation result. Modifications happen after operations, so an update call is required.


Event Pipeline in Plugin:

When we run our Plugin, it is executed based on the Even pipeline :

 

·       Pre-Validation:- Security checks being performed to verify the calling or logged-on user has the correct permissions to perform the intended operation.

The Stage Value is 10.

For Example – In the “delete” plugin. If you need any information about the child records, the deleted plugin must be pre-validation.

·       Pre-Operation:- Execute before the main system operation. Plug-ins registered in this stage are executed within the database transaction.

The Stage Value is 20.

For Create message, this operation does not allow you access to the GUID generated after the creation of the record.

 

·       Core Operation:- The main operation of the system, such as create, update, delete, and so on. No custom plug-ins can be registered at this stage.

The Stage Value is 30.

 

·       Post-Operation:- Plug-ins that are to execute after the main operation. Plug-ins registered in this stage are executed within the database transaction.

The Stage Value is 40. 

 

Run in User’s Context: 

As we are creating a follow-up task on the creation of the account entity, we need to select the Run in User’s Context as a Calling user.

Suppose we select a user who does not have the privilege to create an activity task, then the plugin will not run-on execution.

Now, if we check the System, Jobs. You will see the plugin failed to execute.




Here are some other links for Troubleshooting and learning:

·       Plugin in Dynamic 365 CRM

·       Connect to Dynamic 365 CRM from Console App using Azure Authentication

·       Could not load file or assembly 'System.Net.Http, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' or one of its dependencies

·       Unable to Login to Dynamics CRMOrganizationWebProxyClient is null

·       Assembly 'Microsoft.Crm.Sdk.Proxy' with identity 'Microsoft.Crm.Sdk.Proxy, Version=9.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' uses 'Microsoft.Xrm.Sdk, Version=9.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' which has a higher version than referenced assembly 'Microsoft.Xrm.Sdk' with identity 'Microsoft.Xrm.Sdk, Version=8.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35'

·       Could not load file or assembly 'Microsoft.Xrm.Sdk, Version=9.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference.

·       Could not load file or assembly 'Microsoft.Xrm.Sdk, Version=6.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' or one of its dependencies





Wednesday, December 22, 2021

Connect to Dynamic 365 CRM from Console App using Azure Authentication

In this blog, I would try to demonstrate how to connect to Dynamics 365 CRM from a console application using Azure authentication. We will try to understand this in the following way:

1)     Will start with .NET Code and update it with the required information at the end.

2)     Register an application on Azure that will help us get connected to CRM.

3)     Create an Application User in Dynamic CRM and assign a security role


Step by Step Plugin creation in Dynamic 365 CRM 


Step 1) .NET Code 

Note: Make sure your Target Framework is 4.6.2 or Above



Create a console application and add required Microsoft assemblies using NuGet Package Manager.



Add Microsoft.CrmSdk.xrmTooling.CoreAssembly.


Note: Microsoft.CrmSdk.xrmTooling.CoreAssembly version should be 9.1.0.13 or higher in order to connect using ClientSceret


Now, copy the below code and you need to replace highlighted values

  • Org URL,
  • Application Client ID
  • Client Secret Value


using System;

using System.Collections.Generic;

using System.Text;

using Microsoft.Xrm.Sdk;

using Microsoft.Xrm.Tooling.Connector;

 

namespace ConsoleAzure

{

  class Program

  {

    static void Main(string[] args)

    {

      IOrganizationService orgService;

      orgService = Connect.GetOrganizationServiceClientSecret(

                     "3f9b1a74-f463-422d-a436-750a56ac169e",// Application Client ID

                     "q7E7Q~RRJ1EEcYwDqX7Z9IP0h58ZoEhGk3lPt",//Client Secret

                     "https://org1fe5ad12.crm8.dynamics.com/");// Application URL

 

      Entity acc = new Entity("account");

      acc["name"] = "dddd";

      var createacc = orgService. Create(acc);

      Console.WriteLine("Account created!");

    }

  }

 

  class Connect

  {

    public static IOrganizationService GetOrganizationServiceClientSecret(string clientId, string clientSecret, string organizationUri)

    {

      try

      {

ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls;

        var conn = new CrmServiceClient($@"AuthType=ClientSecret;url={organizationUri};ClientId={clientId};ClientSecret={clientSecret}");

 

return conn.OrganizationWebProxyClient != null ? conn.OrganizationWebProxyClient : (IOrganizationService)conn.OrganizationServiceProxy;

      }

      catch (Exception ex)

      {

        Console.WriteLine("Error while connecting to CRM " + ex.Message);

        Console.ReadKey();

        return null;

      }

    }

  }

}

Step 2) Register an application on Azure

Visit https://portal.azure.com/#home 

Search for App Registration

Click on App Registration then click on New registration.


Click on New Registration and provide the below values.


Name: Console App, 

Supported Account Type as Single Tenant.

Redirect URI as http://localhost


Now click on Register.




After registration note application (client) ID things. We need to update it in our code.







Next, we must provide API permission to APP.

Go to API Permissions option Click on Add Permission and in the list Select Dynamics CRM.


Then Select Delegated Permission. Select the User Impersonation permission. Then click Add Permission button.



Next, We have to Grant Admin Consent for the permission. Click the Grant admin consent and click Yes.



Next, we have to generate a Client Secret for the App. In the App click on Certificates & Secrets. Click on New client Secret.

Provide a name and choose Expires month and click Add.


We need to copy the Secret ID and value. Because the value cannot be copied after some time.



Step 3) Application User in Dynamic CRM 

We need to now configure the Application User. Go to Advanced Settings and Choose Security and Select Users. Change the View to Application User and click on Add new User.


Now provide the Client ID we have copied from Azure Active Directory in the Application ID field and save the record.


 Other fields will be auto-populated after clicking on save. We need to assign Security role as our last step in this


Assign them a security role.