使用BypassCustomPluginExecution参数忽略插件逻辑

Posted luoyong0201

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用BypassCustomPluginExecution参数忽略插件逻辑相关的知识,希望对你有一定的参考价值。

我是微软Dynamics 365 & Power Platform方面的工程师/顾问罗勇,也是2015年7月到2018年6月连续三年Dynamics CRM/Business Solutions方面的微软最有价值专家(Microsoft MVP),欢迎关注我的微信公众号 MSFTDynamics365erLuoYong ,回复467或者20220414可方便获取本文,同时可以在第一间得到我发布的最新博文信息,follow me!

在做项目的时候有时候有这种临时需求,使用管理员来做部分操作的时候希望跳过自己注册的插件/实时工作流逻辑,可能你想到的办法是先暂停这些插件/实时工作流,等处理完毕后再启用起来。我今天的博文介绍一种新的方法,官方文档请参考 ​​Bypass Custom Business Logic​​ 。

为了演示效果,我先用如下代码注册一个插件:

using Microsoft.Xrm.Sdk;
using System;

namespace D365.Plugins

public class AccountPreUpdate : IPlugin

public void Execute(IServiceProvider serviceProvider)

ITracingService tracingService = (ITracingService)serviceProvider.GetService(typeof(ITracingService));
tracingService.Trace($"Enter AccountPreUpdate on DateTime.UtcNow.ToString()");
IPluginExecutionContext context = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));
if (context.InputParameters.Contains("Target") && context.InputParameters["Target"] is Entity)

//插件针对的当前实体记录,对于Pre Update来讲,该对象包括了所有更改的字段值,若字段值没有更改,则不会存在targetEntity中
Entity targetEntity = (Entity)context.InputParameters["Target"];
if (targetEntity.Contains("telephone1"))

var telephone1 = targetEntity.GetAttributeValue<string>("telephone1");
if (string.IsNullOrEmpty(telephone1))

throw new InvalidPluginExecutionException("主要电话不能为空!");

else if (telephone1.Length < 8)

throw new InvalidPluginExecutionException("主要电话不能少于8个字符!");






注册在account实体的Update消息的Pre Operation阶段,监控telephone1字段,如下:

使用BypassCustomPluginExecution参数忽略插件逻辑_Dynamics


然后如果我在界面上将主要电话设置为7个字符会报错如下:

使用BypassCustomPluginExecution参数忽略插件逻辑_Dynamics


但是我如果用下面的代码来更新的话,你会看到更新成功:

和普通的​​更新记录的代码​​的差别就是在RequestHeader中加了一个参数MSCRM.BypassCustomPluginExecution,并将其值设置为true。

var entity = ;
entity.telephone1 = 1234567;
var clientUrl = Xrm.Utility.getGlobalContext().getClientUrl();
var req = new XMLHttpRequest();
req.open("PATCH", `$clientUrl/api/data/v9.2/accounts($Xrm.Page.data.entity.getId().replace(,).replace(,))`);
req.setRequestHeader("Accept", "application/json");
req.setRequestHeader("Content-Type", "application/json; charset=utf-8");
req.setRequestHeader("OData-MaxVersion", "4.0");
req.setRequestHeader("MSCRM.BypassCustomPluginExecution", true);
req.setRequestHeader("OData-Version", "4.0");
req.onreadystatechange = function ()
if (this.readyState == 4)
req.onreadystatechange = null;
if (this.status == 204)
console.log(Updated);

else
var error = JSON.parse(this.response).error;
Xrm.Navigation.openErrorDialog( message: error.message );


;
req.send(JSON.stringify(entity));

使用BypassCustomPluginExecution参数忽略插件逻辑_Dynamics


如果是使用组织服务呢?下面是示例代码:

这种使用CrmServiceClient的方法,BypassPluginExecution 参数设置后,后续的请求都会使用设置的值。

CrmServiceClient crmServiceClient = new CrmServiceClient(ConfigurationManager.AppSettings["connectStr"]);
if (crmServiceClient.IsReady)

Console.WriteLine($"连接到Dynamics 365环境 (crmServiceClient.ConnectedOrgFriendlyName) 成功");
crmServiceClient.BypassPluginExecution = true;
Entity accountEntity = new Entity("account", Guid.Parse("b39f780f-f984-ec11-8d20-0022485940f2"));
accountEntity["telephone1"] = "7654321";
crmServiceClient.Update(accountEntity);


那如果是在插件中呢,也可以嘛?答案是也可以,但是要稍微变化下,比如下面是示例:

可以看到不能直接使用Update, Create, Delete等消息,

需要转换成使用 UpdateRequest, CreateRequest, DeleteRequest 等类,通过组织的Execute方法来执行。

这种方法每个Execute执行之前都要设置一次BypassCustomPluginExecution参数才行。

var updateEntity = new Entity("account", Guid.Parse("b39f780f-f984-ec11-8d20-0022485940f2"));
updateEntity["telephone1"] = "7654321";
var updateRequest = new UpdateRequest()

Target = updateEntity
;
updateRequest.Parameters.Add("BypassCustomPluginExecution", true);
orgSvc.Execute(updateRequest);

这里还设计到权限问题,因为我之前演示使用的账号具有系统管理员角色,所以不会碰到权限问题。若是没有这个角色,会碰到权限问题,这个需要的权限名称是prvBypassCustomPlugins,Guid是 148a9eaf-d0c4-4196-9852-c3a38e35f6a1 ,但是这个权限没有界面来操作添加给某个角色,只能通过代码,因为官方文档上有代码,所以我就直接copy附在文中供各位参考:

Web API版本

POST [Organization URI]/api/data/v9.1/roles(<id of role>)/Microsoft.Dynamics.CRM.AddPrivilegesRole HTTP/1.1
Content-Type: application/json
Accept: application/json
OData-MaxVersion: 4.0
OData-Version: 4.0


"Privileges": [

"PrivilegeId": "148a9eaf-d0c4-4196-9852-c3a38e35f6a1",
"Depth": "3"

]


组织服务版本:

var request = new AddPrivilegesRoleRequest

RoleId = new Guid("<id of role>"),
Privileges = new[]
new RolePrivilege
PrivilegeId = new Guid("148a9eaf-d0c4-4196-9852-c3a38e35f6a1"),
Depth = PrivilegeDepth.Global


;
svc.Execute(request);


最后值得一提的是,跳过的是自定义或者第三方供应商的插件/实时工作流逻辑,并不会跳过微软核心插件和微软作为发布者的插件/实时工作流。

以上是关于使用BypassCustomPluginExecution参数忽略插件逻辑的主要内容,如果未能解决你的问题,请参考以下文章

在使用加载数据流步骤的猪中,使用(使用 PigStorage)和不使用它有啥区别?

今目标使用教程 今目标任务使用篇

Qt静态编译时使用OpenSSL有三种方式(不使用,动态使用,静态使用,默认是动态使用)

MySQL db 在按日期排序时使用“使用位置;使用临时;使用文件排序”

使用“使用严格”作为“使用强”的备份

Kettle java脚本组件的使用说明(简单使用升级使用)