📜  Microsoft Dynamics CRM-插件

📅  最后修改于: 2020-11-20 06:03:43             🧑  作者: Mango


插件是与Microsoft Dynamics CRM集成在一起的自定义业务逻辑,用于修改或扩展平台的标准行为。插件充当事件处理程序,并注册为在CRM中的特定事件上执行。插件使用C#或VB编写,可以在同步或异步模式下运行。

您将编写插件的一些场景是-

  • 您想要执行一些业务逻辑,例如在创建或更新CRM记录时更新记录的某些字段或更新相关记录等。

  • 您希望在某些事件(例如保存或更新记录)上调用外部Web服务。

  • 您想在打开任何记录时动态计算字段值。

  • 您希望自动化过程,例如在CRM中的某些事件上向客户发送电子邮件。

活动框架

CRM中的事件处理框架通过将同步和异步插件请求传递到事件执行管道来对其进行处理。每当事件触发插件逻辑时,都会将消息发送到CRM组织Web服务,在该消息中,其他插件或平台的任何核心操作都可以读取或修改该消息。

插件管道阶段

整个插件管道分为多个阶段,您可以在这些阶段注册自定义业务逻辑。指定的管道阶段指示插件代码在插件执行周期的哪个阶段运行。在下表中所有指定的管道阶段中,您只能在事件前和事件后注册自定义插件。您无法在Platform Core Main Operations上注册插件。

Event Stage Name Description
Pre-Event Pre-validation Stage in the pipeline for plug-ins that are to execute before the main system operation. Plug-ins registered in this stage may execute outside the database transaction.
Pre-Event Pre-operation Stage in the pipeline for plug-ins that are to executed before the main system operation. Plugins registered in this stage are executed within the database transaction.
Platform Core Operation MainOperation Intransaction,the main operation of the system, such as create, update, delete, and so on. No custom plug-ins can be registered in this stage. For internal use only.
Post-Event Post-operation Stage in the pipeline for plug-ins which are to executed after the main operation. Plug-ins registered in this stage are executed within the database transaction.

每当CRM应用程序调用事件(例如保存或更新记录)时,就会发生以下一系列操作:

  • 该事件触发Web服务调用,并且执行通过事件管道阶段(事件前,平台核心操作,事件后)传递。

  • 该信息在内部打包为OrganizationRequest消息,最后发送到内部CRM Web服务方法和平台核心操作。

  • 组织请求消息首先由事件前插件接收,事件插件可以在将信息传递给平台核心操作之前对其进行修改。在平台核心操作之后,该消息将打包为OrganizationResponse并传递到操作后插件。后操作插件可以有选择地修改此信息,然后再将其传递给异步插件。

  • 插件以上下文对象的形式接收此信息,该对象将传递到Execute方法,然后进行进一步处理。

  • 在所有插件处理完成之后,执行将传递回触发事件的应用程序。

插件消息

消息是注册插件(或业务逻辑)的事件。例如,您可以在“创建联系人的消息”实体上注册插件。每当创建新的联系人记录时,这将触发业务逻辑。

对于自定义实体,以下是基于该实体是用户拥有还是组织拥有的受支持消息。

Message Name Ownership Type
Assign User-owned entities only
Create User-owned and organization-owned entities
Delete User-owned and organization-owned entities
GrantAccess User-owned entities only
ModifyAccess User-owned entities only
Retrieve User-owned and organization-owned entities
RetrieveMultiple User-owned and organization-owned entities
RetrievePrincipalAccess User-owned entities only
RetrieveSharedPrincipalsAndAccess User-owned entities only
RevokeAccess User-owned entities only
SetState User-owned and organization-owned entities
SetStateDynamicEntity User-owned and organization-owned entities
Update User-owned and organization-owned entities

对于默认的开箱即用实体,有100多种受支持的消息。这些消息中的某些消息适用于所有实体,而某些消息特定于某些实体。您可以在SDK内的excel文件中找到受支持消息的完整列表: SDK \ Message-entity对插件的支持.xlsx

编写插件

在本节中,我们将学习编写插件的基础知识。我们将创建一个示例插件,该插件将创建一个Task活动,以便在将新客户添加到系统时(即,在CRM中创建新的Contactrecord时)跟进该客户。

首先,您需要包括对Microsoft.Xrm.Sdk命名空间的引用。 CRM SDK包含所有必需的SDK程序集。假设您已经在第2章中下载并安装了SDK,请打开Visual Studio。创建一个类型为“类库”的新项目。您可以将项目命名为SamplePlugins,然后单击“确定”。

Mscrm插件创建与解决方案

Microsoft.Xrm.Sdk程序集的引用添加到您的项目。该程序集存在于SDK / Bin中

Mscrm插件添加解决方案参考

现在,创建一个名为PostCreateContact.cs的类,并从IPlugin扩展该类。到现在为止,您的代码将如下所示。

Mscrm插件示例代码

您还需要添加对System.Runtime.Serialization的引用。添加必需的引用后,将以下代码复制到PostCreateContact类中。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Xrm.Sdk;

namespace SamplePlugins {
   public class PostCreateContact:IPlugin {
      /// A plug-in that creates a follow-up task activity when a new account is created.
      /// Register this plug-in on the Create message, account entity,
      /// and asynchronous mode.

      public void Execute(IServiceProviderserviceProvider) {
         // Obtain the execution context from the service provider.
         IPluginExecutionContext context =(IPluginExecutionContext)
            serviceProvider.GetService(typeof(IPluginExecutionContext));

         // The InputParameters collection contains all the data
            passed in the message request.

         if(context.InputParameters.Contains("Target")&&
            context.InputParameters["Target"]isEntity) {
            
            // 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 customer.";
               followup["description"] =
                  "Follow up with the customer. Check if there are any new issues
                  that need resolution.";
               
               followup["scheduledstart"] = DateTime.Now;
               followup["scheduledend"] = DateTime.Now.AddDays(2);
               followup["category"] = context.PrimaryEntityName;

               // Refer to the contact in the task activity.
               if(context.OutputParameters.Contains("id")) {
                  Guid regardingobjectid = new Guid(context.OutputParameter
                     s["id"].ToString());
                  string regardingobjectidType = "contact";
                  followup["regardingobjectid"] = 
                     new EntityReference(rega rdingobjectidType,regardingobjectid);
               }
               
               // Obtain the organization service reference.
               IOrganizationServiceFactory serviceFactory =
                  (IOrganizationSer viceFactory)serviceProvider.GetService
                  (typeof(IOrganizationServiceFactory));
               IOrganizationService service = 
                  serviceFactory.CreateOrganizationService(context.UserId);

               // Create the followup activity
               service.Create(followup);
            } catch(Exception ex) {
               throw new InvalidPluginExecutionException(ex.Message);
            }
         }
      }
   }
}

以下是此代码的逐步说明-

步骤1-通过将IServiceProvider对象作为其参数来实现Execute方法。服务提供者包含对您将在插件中使用的许多有用对象的引用。

步骤2-使用IServiceProvider的GetService方法获取IPluginExecutionContext对象。

步骤3-从上下文对象的InputParameters集合中获取目标实体的对象。该Entity类对象引用了我们的插件将在其上注册的Contact实体记录。

步骤4-然后创建任务实体的对象,并设置适当的主题,描述,日期,类别和关于objectid。 Aboutobjectid指示正在为其创建该活动记录的联系人记录。您可以看到该代码使用context.OutputParameters获取父Contact记录的ID,并将其与您创建的Task实体记录相关联。

步骤5-使用IServiceProvider对象创建IOrganizationServiceFactory对象。

步骤6-使用IOrganizationServiceFactory对象创建IOrganizationService对象。

步骤7-最后,使用此服务对象的Create方法。它创建了后续活动,该活动已保存在CRM中。

签名插件程序集

本节仅在您首次注册插件程序集时适用。您需要使用密钥登录程序集才能部署插件。右键单击解决方案,然后单击属性。

Mscrm插件解决方案属性

从左侧选项中选择“签名”选项卡,然后选中“对程序集签名”选项。然后,从“选择强名称密钥文件”选项中选择“新建”。

Mscrm插件标牌组装

输入密钥文件名作为sampleplugins(可以是您想要的任何其他名称)。取消选中“使用密码保护我的密钥文件”选项,然后单击“确定”。单击保存。

Mscrm插件标牌组合件添加键

最后,构建解决方案。右键单击→构建。构建解决方案将生成程序集DLL,我们将在下一章中使用它来注册此插件。

插件中的异常处理

通常,您的插件逻辑将需要处理运行时异常。对于同步插件,您可以返回InvalidPluginExecutionException异常,该异常将向用户显示错误对话框。错误对话框将包含传递给异常对象的Message对象的自定义错误消息。

如果您看一下我们的代码,我们会在catch块中引发InvalidPluginExecutionException异常。

throw new InvalidPluginExecutionException(ex.Message); 

结论

插件对于任何自定义CRM实施绝对至关重要。在本章中,我们着重于了解事件框架模型,管道阶段,消息以及编写示例插件。在下一章中,我们将在CRM中注册此插件,并在端到端场景中看到它的运行。