Dynamic CRM 2013学习笔记(二)插件基本用法及调试
插件是可与 Microsoft Dynamics CRM 2013 和 Microsoft Dynamics CRM Online 集成的自定义业务逻辑(代码),用于修改或增加平台的标准行为。也可以将插件认为是针对 Microsoft Dynamics CRM 触发的事件的处理程序。您可以让插件订阅或注册已知事件集,以便在事件发生时运行您的代码。
一、基本用法
1. 要继承IPlugin,并实现Excute方法 ( 1- 3 行)
2. 从service provide 里获取执行上下文 ( 5行 )
3. 我们可以检查触发插件的实体名称 ( 7 – 11 行)
4. 还可以检查触发的事件,是create, update 还是delete (12 – 16行 )
5. 输入参数里获取触发的实体 ( 20 行 )
6. 通过service factory获取IOrganizationService,当CreateOrganizationService方法的参数为null时,表示的是系统用户,当参数为context.UserId 或Guid.Empty时,表示的是当前用户 ( 21 – 23行)
7. 最后是DoAction方法,插件的逻辑就可以在这里实现了。
public class new_marketing_plan_updatePost : IPlugin
{
public void Execute(IServiceProvider serviceProvider)
{
IPluginExecutionContext context = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));
//检查实体名称
if (context.PrimaryEntityName.ToLower() != "new_marketing_plan")
{
throw new InvalidPluginExecutionException("Entity is not Marketing Plan");
}
// 检查消息是否正确
if (context.MessageName.ToLower() != "update")
{
throw new InvalidPluginExecutionException("message is not Update");
}
if (context.InputParameters.Contains("Target") && context.InputParameters["Target"] is Entity)
{
Entity entity = (Entity)context.InputParameters["Target"];
IOrganizationServiceFactory serviceFactory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));
IOrganizationService userService = serviceFactory.CreateOrganizationService(context.UserId);
IOrganizationService adminSerivce = serviceFactory.CreateOrganizationService(null);
DoAction(adminSerivce, userService, entity);
}
}
}
二、删除插件
根据上面的介绍,获取当前实体的时是用的这种方式:
Entity entity = (Entity)context.InputParameters["Target"];
但是对于删除事件,就不能这样获取了,这时应该通过下面的方式来获取:
EntityReference er = context.InputParameters["Target"] as EntityReference;
CurrentEntity = new Entity(er.LogicalName);
CurrentEntity.Id = er.Id;
第一次写删除的插件,这个问题困扰了我好长时间。
三、用Unit Test调试插件
1. 下载Rhino.Mocks
2. 添加引用到unit test项目
Microsoft.Crm.sdk.proxy
Microsoft.Xrm.Client
Microsoft.Xrm.Sdk
Rhino.Mocks
System.Runtime.Serialization
以及要调试的项目,这里是MarketingManage
3. 初始化unit test
这里,我们用Rhino.Mocks来模拟IServiceProvider, IPluginExecutionContext, IOrganizationServiceFactory, IOrganizationService等变量。
(1)获取CRM连接 ( 12 – 14 行 )
(2)用Rhino.Mocks来模拟IServiceProvider, IPluginExecutionContext, IOrganizationServiceFactory, IOrganizationService ( 16 – 20 行 )
public IServiceProvider serviceProvider;
public IPluginExecutionContext context;
public IOrganizationServiceFactory factory;
public IOrganizationService service;
public String prefix = "new_";
public String customEntityName;
[TestInitialize]
public void GetOrgService()
{
//跨域调试采用这个URL,同域用http://me-crm-01/crm即可
string server = "Url=http://crmdev:5555/CRM;Domain=xxx;Username=crmtest02;Password=abc-123";
var myConnection = CrmConnection.Parse(server);
serviceProvider = MockRepository.GenerateMock<IServiceProvider>();
context = MockRepository.GenerateMock<IPluginExecutionContext>();
factory = MockRepository.GenerateMock<IOrganizationServiceFactory>();
service = MockRepository.GenerateMock<IOrganizationService>();
service = new OrganizationService(myConnection);
}
4. 调试
下面就进入调试方法了:
(1)模拟一个Entity当作触发插件的实体 (4- 13行 )
(2)直接调试插件里的DoAction方法 (15-16 行 )
[TestMethod]
public void TestApproePaymentrequest()
{
ParameterCollection paramBag = new ParameterCollection();
XRMHelper helper = new XRMHelper(service);
Entity currentent = helper.GetInfoByAttrValue("new_marketing_plan", "new_name", "20140910-000004")[0];
paramBag.Add("Target", currentent);
context.Stub(x => x.InputParameters).Return(paramBag);
serviceProvider.Stub(x => x.GetService(typeof(IPluginExecutionContext))).Return(context);
serviceProvider.Stub(x => x.GetService(typeof(IOrganizationServiceFactory))).Return(factory);
factory.Stub(x => x.CreateOrganizationService(null)).Return(service);
new_marketing_plan_updatePost mp = new new_marketing_plan_updatePost();
mp.DoAction(service, service, currentent);
}
四、 日志记录和跟踪
有时插件写好了,Unit Test也通过了,但注册完插件,在真实环境里运行时,还是报错,比如像Dynamic CRM 2013学习笔记(-)插件输入实体参数解析里遇到的错误,这时我们就要用到跟踪功能。
跟踪功能可以提供运行时插件信息,以帮助诊断插件故障的原因,从而帮助开发人员解决插件问题。
此处所说的跟踪不同于 ASP.NET 跟踪。跟踪是在 Microsoft Dynamics CRM SDK 中通过使用跟踪服务 ITracingService 而实施的。开发人员在插件代码中添加 Trace 语句,然后构建并部署插件。在执行过程中,只有当插件在运行时向平台传回异常时,用户才会看到跟踪信息。对于同步注册插件,跟踪信息会显示在 Microsoft Dynamics CRM Web 应用程序的对话框中。对于异步注册插件,跟踪信息会显示在 Web 应用程序中“系统作业”窗体的“详细信息”区域中。此类信息的数量和特点将取决于开发人员为插件编写的代码。
实施此类型跟踪的主要原因是为了支持 Microsoft Dynamics CRM 中的隔离(沙盒)插件和自定义工作流活动功能。沙盒自定义代码无法将信息写入到系统事件日志或文件系统中。通过实施跟踪服务,就为沙盒插件和自定义工作流活动提供了一种在抛出异常时输出运行时信息的方法。此外,非沙盒插件也支持跟踪功能。
用法:
(1) 初始化
ITracingService tracingService = (ITracingService)serviceProvider.GetService(typeof(ITracingService));
(2) 添加Trace语句tracingService.Trace("In DoAction method");实际上,我们可以在每个方法里try catch一下,这下可以快速定位到是哪个方法报错,再通过Trace语句来精确定位。例如:catch (Exception ex)
{
throw new InvalidPluginExecutionException("GetQueryExpression error : " + ex.Message);
}下面是我的一个真实的case:Dynamic CRM 2013学习笔记 系列汇总
Dynamic CRM 2013学习笔记(二)插件基本用法及调试的更多相关文章
- Dynamic CRM 2013学习笔记(十二)实现子表合计(汇总,求和)功能的通用插件
上一篇 Dynamic CRM 2013学习笔记(十一)利用Javascript实现子表合计(汇总,求和)功能 , 介绍了如何用js来实现子表合计功能,这种方法要求在各个表单上添加js方法,如果有很多 ...
- Dynamic CRM 2013学习笔记(二十二)插件里调用WCF服务
1. 添加service: 2.调用WCF BasicHttpBinding myBinding = new BasicHttpBinding(); myBinding.Name = &q ...
- Dynamic CRM 2013学习笔记(四)单据编号及插件批量注册工具
基本上每个实体form上都会有单据编号,而且不同的实体编号要求还不太一样,这时就需要一个通用的单据编号插件,可配置以应对不同的需求. 下面简单介绍下实现步骤: 1. 创建二个实体,以保存各实体所要求的 ...
- Dynamic CRM 2013学习笔记(二十)字段改变事件的二种实现方法
CRM里有二种方式实现字段change事件,一种是在form里,一种完全通过js来实现.本文介绍下二者的用途及区别. 1. Form里用法 这种方式估计其实也是添加一个js的function. 这种方 ...
- Dynamic CRM 2013学习笔记(三十二)自定义审批流3 - 节点及实体配置
上次介绍了<Dynamic CRM 2013学习笔记(十九)自定义审批流1 - 效果演示> 以及如何配置自定义审批流的按钮:<Dynamic CRM 2013学习笔记(二十一)自定义 ...
- Dynamic CRM 2013学习笔记(三十五)自定义审批流6 - 审批通过后,再审批 - 二次审批
最近有个特殊的需求,客户想做二次审批,就是审批通过后,再走一次审批流程.最开始一想,这还不简单,审批通过后,直接把状态改成draft就完了,后来一试,发现一堆问题,比如第一次审批完后,界面是不允许修改 ...
- Dynamic CRM 2013学习笔记(四十二)流程5 - 实时/同步工作流(Workflow)用法图解
实时工作流跟插件一样,也是用事件执行管道来执行,能在pre,post或核心操作中执行.跟插件一样,不能在创建之前和删除之后执行.如果执行过程中有异常发生,会取消并回滚整个操作.实时工作流里所有的活动和 ...
- Dynamic CRM 2013学习笔记(一)插件输入实体参数解析
1. 问题描述 最近新建了一个post事件的插件,传入的参数处理如下: 1: if (context.InputParameters.Contains("Target") &a ...
- Dynamic CRM 2013学习笔记(二十三)CRM JS智能提示(CRM 相关的方法、属性以及页面字段),及发布前调试
我们知道在CRM的js文件里引用XrmPageTemplate.js后,就可以实现智能提示,但每个js文件都引用太麻烦了,其实可以利用vs的功能让每个js文件自动实现智能提示CRM的js: 另外,我们 ...
随机推荐
- Windows下Python工具pip的安装
1.打开pip的文档官网 https://pip.pypa.io/en/stable/ ,进入installation.在installation里,我们需要的是get-pip.py这个脚本. 选中后 ...
- input输入子系统
一.什么是input输入子系统? 1.Linux系统支持的输入设备繁多,例如键盘.鼠标.触摸屏.手柄或者是一些输入设备像体感输入等等,Linux系统是如何管理如此之多的不同类型.不同原理.不同的输入信 ...
- C++ dll调用
HINSTANCE PH=LoadLibrary(_T("APlayerCaller.dll")); HWND hwnd = AfxGetMainWnd()->m_hWnd; ...
- X/Y型文案
[X/Y型文案] X型文案人,他们更像你语言学家.修辞学家和诗人,他们的日常工作就是想创意.查词典和构思修辞,以想办法用华丽的表达来描述产品. Y型文案往往并不华丽,有时甚至只不过是简单地描绘出用户心 ...
- Groovy basic
1. print println "Hello Groovy!" you can use java in Groovy System.out.println("Hello ...
- 读取assets文件夹下图片(ods_interview)
今天看了一道题,现在总结一下里面使用到的知识点: 1.assets文件的访问: 原文出处:http://blog.csdn.net/fengyuzhengfan/article/details/383 ...
- 第一次正式小用Redis存储
由于要做一个同一个页面上多种图表数据的下载,考虑到Azure上面的session很不稳定(可用Redis provider存储session,较稳定),故决定改为Azure支持的Redis,顺便也学习 ...
- C# 编程指南-事件
来自微软官方的msdn: 首页:https://msdn.microsoft.com/zh-cn/library/ms366768.aspx 1.如何:订阅和取消订阅事件 2.如何:发布符 ...
- 第四章 Leader选举算法分析
Leader选举 学习leader选举算法,主要是从选举概述,算法分析与源码分析(后续章节写)三个方面进行. Leader选举概述 服务器启动时期的Leader选举 选举的隐式条件便是ZooKeepe ...
- hihoCode 1078 : 线段树的区间修改
#1078 : 线段树的区间修改 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 对于小Ho表现出的对线段树的理解,小Hi表示挺满意的,但是满意就够了么?于是小Hi将问题 ...