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: 另外,我们 ...
随机推荐
- Ubuntu14.04安装MySQL-python异常: mysql_config: not found,Command "python setup.py egg_info" failed with error code 1 in /tmp/pip-build-MJWMPd/MySQL-python/
aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAABUoAAAE8CAIAAACZ6RwMAAAgAElEQVR4nOydaVxTx9fHn9dhKWqltv
- C# 队列集合的使用
using System; using System.Collections.Generic; using System.Text; using System.Collections; namespa ...
- localstorage,sessionstorage使用
今天看了一下HTML5,也算是简单的学习一下吧,HTML5 提供了两种在客户端存储数据的新方法:localstorage,sessionstorage. localStorage - 没有时间限制的数 ...
- sqlserver表数据导出为insert into语句
<1>select 'insert into table_name (name,code) values ('''+name+''','''+code+''');' sql_str fr ...
- C语课设心得分享(二)
咱们今儿说说IDE的事儿. IDE是「集成开发环境」的意思,比如咱们常用的VC6.0,就是开发C语言所用的IDE的一种.对于IDE的认识,可能有些朋友有点儿模糊,咱们捋一捋,我也会给出一些IDE方面的 ...
- 点亮一个led灯
/********************************* 代码功能:点亮一个led灯 使用函数: pinMode(引脚号,模式); digitalWrite(引脚号,电平状态); //默认 ...
- iOS模拟器设置输入中文
1.打开模拟器,选择Settings; 2.选择General ->KeyBoard ->KeyBoards,选择中文输入法Chinese(Simplified)即可 以前尝试试了很多方 ...
- 使用Debussy+ModelSim快速查看前仿真波形
sim.do文件 quit -sim set PATH1 D:/Program/modelsim/vivado_lib set PATH2 D:/Program/Vivado/Vivado/2014. ...
- centos 添加 composer
下载安装包 curl -sS https://getcomposer.org/installer | php 把 composer 把复制到 /usr/bin/composer mv composer ...
- StringBuffer
1.StringBuffer StringBuffer类和String一样,也用来代表字符串,只是由于StringBuffer的内部实现方式和String不同,所以StringBuffer在进行字符串 ...