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: 另外,我们 ...
随机推荐
- TCP控制拥塞的四种算法:慢开始,拥塞避免,快重传,快恢复
我们在开始假定: 1:数据是单方向传递,另一个窗口只发送确认. 2:接收方的缓存足够大,因此发送方的大小的大小由网络的拥塞程度来决定. 一:慢开始算法和拥塞避免算法 发送方会维持一个拥塞窗口,刚开始的 ...
- [vivado系列]设置Xilinx Documention Navigator
版本:2015.1 ------------------------------------------ 这是一个很便利FPGA工程师的文档整理收纳神器. 针对个人使用上的习惯,进行简单的2项设置. ...
- QT 使用jsoncpp
QT 使用jsoncpp 编译jsoncpp 编译前先安装好python,scons,解压jsoncpp到目录e:\jsconcpp,查看目录下的readme,有关于编译的说明的,根据说明做相应操作就 ...
- C#十种语法糖
语法糖 指计算机语言中添加的某种语法,这种语法对语言的功能并没有影响,但是更方便程序员使用.通常来说使用语法糖能够增加程序的可读性,从而减少程序代码出错的机会.需要声明的是"语法糖" ...
- error in opening zip file 1 错误
项目部署服务启动时会出现: error in opening zip file 1 错误 原来是不同服务器编译过的jar包直接下载后发布有问题,重新上传本地编译好的lib下面的jar包后,启动服务,正 ...
- 《机器学习实战》学习笔记——第2章 KNN
一. KNN原理: 1. 有监督的学习 根据已知事例及其类标,对新的实例按照离他最近的K的邻居中出现频率最高的类别进行分类.伪代码如下: 1)计算已知类别数据集中的点与当前点之间的距离 2)按照距离从 ...
- SQL数据库完全复制
很少摸 Windows 环境下的东西,最近被个 MS SQL Server 的数据库搞得头大.实在不像 MySQL 那样用起来轻车熟路, OrZ ... 本来以为企业管理器里面既然提供了 DTS 数据 ...
- Scrum Meeting (Oct. 27 2014)
软件工程是一门十分有意思的课程,它不仅锻炼了我们开发软件的能力,更是给了我们结队作业的机会,在团队协作中,我们学会了欣赏别人,学会了品鉴自己,学会了如何集思广益凝聚成一个锐意进取的集体.继单人单词查询 ...
- sql 返回xml类型的数据
1, 这中方式可以在Item节点上加一个Items节点作为所有item节点的父节点 SELECT Orders.OrderNumber , ( SELECT ProductID ...
- WebStorm常用设置和常用快捷键
今天下载了最新版本的WebStorm 7.反正又要重新设置一番了,干脆写下来记录到博客里面,免得以后每次忘了还要到处搜索比较麻烦. 加速 禁用多余的插件,关掉没必要的代码检查项.webstorm慢的原 ...