crm sdkrust owneridd是什么类型

MSCRM2011开发指南操作大全[个人经验]
CRM字段类型:
Money(Decimal){SQL更新Money类型字段,需要同时更新_base字段,存在汇率差的时候值不同}
查找:new EntityReference(objecttypename,Guid)
下拉:new OptionSet(Int)
选项集:false/true
时间:DateTime
整数:Integer
十进制数:Decimal
浮点数:Double
单行/多行文本:String
存储列表值:StringMap
存储附件:annotation
CRM,8个基本数据操作:
&&&创建多对多关系
&&&&创建数据
&&&&删除数据
Disassociate &&删除多对多关系
&&&执行请求&
&&&查询一个记录
RetrieveMultiple &查询多个记录
&&&&更新数据&
1.Xrm.Page.context
用户ID:getUserId()
用户角色:getUserRoles()
用户语言:getUserLcid()
组织名称:getOrgUniqueName()
组织语言:getOrgLcid()
路径参数:getQueryStringParameters()
服务器路径:getServerUrl()/getClientUrl()
前追加组织名称:prependOrgName("/WebResource/**")效果:crmtest/WebResource/**
当前主题:getCurrentTheme()
OutLook:isOutlookClient()/isOutlookOnline()
2.Xrm.Page.data.entity
所有页面元素:attributes【forEach(),get(),getLength()】
单个元素:attributes.get("")【同Xrm.Page.getAttribute()】
实体名称:getEntityName()
实体ID:getId()
是否修改:getIsDirty()
保存事件:save()
添加保存时事件:addOnSave()
移出保存时事件:removeOnSave()
3.Xrm.Page.getAttribute("")
取值:getValue()
赋值:setValue()
是否改动:getIsDirty()
表单载入时的值:getInitialValue()[Boolean, optionset]
提交类型:getSubmitMode(),setSubmitMode()//always,never,ditry
必填等级:getRequiredLevel(),setRequiredLevel()//required、none
用户操作等级:getUserPrivilege()//canCreate()、canRead()、canUpdate()
事件:addOnChange(),removeOnChange(),fireOnChange()[强制执行]
其他:getAttributeType(),getFormat(),getMax(),getMaxLength(),getMin(),getName(),getParent(),getPrecision()
optionset:getOption(),getOptions(),getSelectedOption(),getText()
4.Xrm.Page.getControl("")
属性:getAttribute()【同Xrm.Page.getAttribute()】
禁用/启用:setDisabled(true),setDisabled(false),getDisabled()
显示/隐藏:setVisible(true),setVisible(false),getVisible()
描述:setLabel(),getLabel()
聚焦选中:setFocus
刷新:refresh()//仅限SubGrid
其他:addCustomView(),addOption(),removeOption(value),clearOptions(),getControlType(),getData(),setData(),getDefaultView(),setDefaultView(),getName(),getParent(),getSrc(),setSrc(),getInitialUrl(),getObject()
5.Xrm.Page.ui
页面所有控件:controls【forEach(),get(),getLength()】
单个控件:controls.get("")【同Xrm.Page.getControl()】
页面Tab:tabs【forEach(),get(),getLength()】
单个Tab:tabs.get()【sections,getDisplayState(),getLabel(),getName(),getParent(),getVisible(),setDisplayState(),setFocus(),setLabel(),setVisible()】
Tab-Sections:tabs.get(0).sections【forEach(),get(),getLength()】
单个Section:tabs.get(0).sections.get(0)【getLabel(),getName(),getParent(),getVisible(),setLabel(),setVisible(),controls】
页面导航:navigation.items【forEach(),get(),getLength()】
单个导航:navigation.items.get()【getId(),getLabel(),getVisible(),setFocus(),setLabel(),setVisible()】
窗体:formSelector.items【forEach(),get(),getLenght()】
单个窗体:formSelector.items.get()【getId(),getLabel(),navigate()-窗体跳跃】
6.窗体状态
var FORM_TYPE_CREATE = 1;
var FORM_TYPE_UPDATE = 2;
var FORM_TYPE_READ_ONLY = 3;
var FORM_TYPE_DISABLED = 4;
var FORM_TYPE_QUICK_CREATE = 5;
var FORM_TYPE_BULK_EDIT = 6;
var formType = Xrm.Page.ui.getFormType();
刷新当前页面:
window.location.href = window.location.
window.location.reload();
禁用页面所有控件:
Xrm.Page.ui.controls.forEach(function (control, index) {
&control.setDisabled(true);
防止保存事件(需要执行上下文):
function My_PreventSaveFunction(eContext) {
&eContext.getEventArgs().preventDefault();
给Lookup取值赋值:
id:obj.getValue()[0].
name:obj.getValue()[0].
var objList = new Array();
var obj = new Object();
obj.id = accountObj[0].TerritoryId.Id;
obj.name = accountObj[0].TerritoryId.N
obj.typename = accountObj[0].TerritoryId.LogicalN
objList[0] =
Xrm.Page.getAttribute("yto_territory").setValue(accountObj[0].TerritoryId.Id
== null ? null : objList);
Xrm.Page.getAttribute("yto_territory").setSubmitMode("always");
Xrm.Page.data.entity.save();
给OptionSet按条件显示列:
Xrm.Page.getControl("new_counter_type").clearOptions();
var options =
Xrm.Page.getAttribute("new_counter_type").getOptions();
for (var i = 0; i & options. i++) {
&if (options[i].value != 190 &&
options[i].value != 200 && options[i].value!="null" )
&&Xrm.Page.getControl("new_counter_type").addOption(options[i],
Xrm.Page.getControl("new_counter_type").addOption(Xrm.Page.getAttribute("new_counter_type").getOption(190),1);
JS,给日期类型控件赋值:
var fullYear =
Xrm.Page.getAttribute("yto_confirmdate").getValue().getFullYear();
var month =
Xrm.Page.getAttribute("yto_confirmdate").getValue().getMonth() +
var date =
Xrm.Page.getAttribute("yto_confirmdate").getValue().getDate();
Xrm.Page.getAttribute("yto_confirmdate").setValue(new
Date(fullYear, month, date))//厂方确认交货日期+1月
Xrm.Page.data.entity.save();
7.给Lookup添加过滤:
var fetch = '';
Xrm.Page.getControl("new_detailitem").addCustomView("{B9C6A1F4-0A03-424D-B843-E4D9281F8DEB}",
"new_expensesdetail", "根据部门和费用期间筛选", fetch, view, true);
&&modifiedLookupParameter("new_detailitem",
"DisableViewPicker", "1");
A.取fetchxml和viewxml:
高级查找-编辑列-F12-脚本dlg_editview.aspx
frameRender.FetchXml.value
frameRender.LayoutXml.value
B.addCustomView("可用系统视图GUID,以便覆盖","","","","",是否默认视图)
8.用Ribbon
Editor给自定义按钮添加JS事件:Library($webresource:web资源的名称)
9.JS引用了REST等通用JS的方法,需在该实体的窗体库中引用通用JS。
10.Plugin调试步骤:Plugin Registration Tool =& Profile =&
保存ErrorDetail.txt =& Stop Profile =&
Debug,加载ErrorDetail.txt和DLL =& VS附加PlugRegistration.exe到进程
=&Debug Start
11.Plugin抛异常到页面:throw new
InvalidPluginExecutionException("");
12.Plugin取值:
int statuscode = (preImageEntity.Attributes["statuscode"] as
OptionSetValue).V
13.Plugin删除了类文件,还需要去RegisterFile.crmregister删除对应的引用,否则会出现部署失败
14.高级查找-编辑列-F12未出现开发人员工具:IE-Internet选项-安全-Internet-自定义级别-允许网站打开没有地址或状态栏的窗口-禁用
15.是否出现“添加已存在**明细”按钮方法:明细表中主表字段的必填等级=业务必须,则不出现添加已存在按钮,否则出现。
16.删除一个表数据,在Pre-Delete中,已经把与之关联的数据中包含它的字段都NULL了。查询与之关联的数据,不能再通过该字段。
17.货币类型后台赋值:new Money(decimal.Parse())
18.菜单关联视图:
【函数】19.动态载入JS(CRM函数):loadScriptAdv("脚本URL","任意ID",false);
loadScriptAdv(Xrm.Page.context.prependOrgName("/WebResources/fw_rest"),
"55EE635C-91BD-443F-A3E6-56ACEG4E574G", false);
【函数】20.获取Homepage选择的项(CRM函数):getSelected("crmGrid")
【函数】打开模式窗口openStdDlg()
windos.open("");
21.插件异步:异步plugin需要异步服务执行,这个启动时间会比较慢。POST后才会去启动这个操作。另外,异步作业有个特点,就是可还原操作。出错了,改完数据或修正plugin,可以将操作继续执行。
22.VS新建解决方案,选不了组织,因为本机不能识别CRM电脑名,要添加HOSTS映射:172.16.4.217
23.JS给日期控件赋值:Xrm.Page.getAttribute("yto_date").setValue(new
Date()),但是JS取客户机时间,建议在JS赋值的基础上再用PreValidate插件
24.JS刷新CRM视图:Mscrm.Utilities.refreshCurrentGrid(entityTypeCode);
25.注意。报表做时间类型的比对时,在第一行把时间类型参数dbo.fn_LocalTimeToUTC()转成UTC时间。dbo.fn_UTCToLocalTime()转成本地时间
set @startDate=isnull(@startDate,'')
set @startDate=dbo.fn_LocalTimeToUTC(@startDate)
set @endDate=dbo.fn_LocalTimeToUTC(DATEADD(DD,1,@endDate))
26.多条记录拼接为一个字符串:
SELECT @re=@re+','+yto_name FROM yto_order
select @new_businessunit= stuff((select
';'+convert(varchar(50),businessunitid) from businessunit for xml
path('')),1,1,'')
27.导入解决方案之后,需要去检查关于扩展功能的插件有没有出现重复项,删除较早的,不然会出现审批之后,按钮不会改变的问题。
28.不要使用任何系统自带的字段,如状态描述、创建日期来当作单据的字段使用!
29.域用户需要在CRM部署管理器中加入CRM部署管理员,才能进行开发和部署操作。
30.货币类型的字段赋值:=new
Money(decimail)&&&&
!!!,切记。
31.VS链接项目发生安全性的问题,因为CRM服务器和本机的时间相隔超过5分钟。
32.Pre_Create中,不能用entity.Id来做引用,因为目前该数据尚不存在。
34.VS解决方案不显示CRM视图:修改“解决方案.sln”文件,添加节点
GlobalSection(CRMSolutionProperties) = preSolution
&SolutionIsBoundToCRM = True
EndGlobalSection
35.转REST获取的日期类型(从“/Date***”到“Fri Nov 1 00:00:00 UTC+0800
function dateReviver(value) {
&&& if (typeof
value === 'string') {
a = /Date\(([-+]?\d+)\)/.exec(value);
&&&&&&&&&&&
return new Date(parseInt(value.replace("/Date(", "").replace(")/",
""), 10));
&&& return
36.REST查询需要的日期类型转换:var myDate = (new
Date()).format("yyyy-MM-ddThh:mm:ss");
37.值为NULL的列查询后不包含在实体中:!Contains("")
38.实体创建的时候可以给ownerid赋值,但更新的时候给ownerid赋值不会更新。
39.CRM组织服务更新日期字段时,DateTime.Now和DateTime.UtcNow插入到数据库的值是一样的。
日期赋值:
entity["date1"]=entity["date2"]是对的(显示:;date1:
16:00:00 date2: 16:00:00);
entity["date1"]=DateTime.Parse(entity["date2"].ToString())是错的(显示:
date1: 8:00:00已错 date2: 16:00:00)
entity["date1"] = DateTime.Now、entity["date1"] =
DateTime.UtcNow,结果是一样的!( 16:00:00)
(DB,Retrieve,Image,Entity上取的都是-8H的,只有页面显示已经+8H)所以JS中和CS中的比较一定要注意。
41.通过数据库还原新组织后,由于顶级组织改变,所有业务部门的guid会改变。
42.CRM数据库新建视图后,给新用户权限,需‘授予’查询的实体和关联实体的视图的‘选择’权限就行了。
43.删除或者更新数据的时候,用最高权限的用户初始化的组织服务。
44.context.SharedVariables插件间的参数传递,注意context不同的时候,获取不到,所以最好用顶级context。
45.关于实体字段“货币”的赋值:service中create和update实体的时候,只有带上货币类型字段,“货币”会自动赋值。
1.发现服务-http://crmpc/XRMServices/2011/Discovery.svc&
(用来发现域下面有哪些组织)
2.SOAP组织服务-http://crmpc/yto/XRMServices/2011/Organization.svc&&
(C#试用的标准的数据服务)
3.OData组织服务-http://crmpc/yto/XRMServices/2011/OrganizationData.svc&&
(平时使用的rest脚本数据服务)
1.[SetStateDynamicEntity]
获取实体:
EntityReference entity =
context.InputParameters.Contains("EntityMoniker") ?
context.InputParameters["EntityMoniker"] as EntityReference :
获取状态:
OptionSetValue state = context.InputParameters["State"] as
OptionSetV
OptionSetValue status = context.InputParameters["Status"] as
OptionSetV
修改状态:
SetStateRequest setState = new SetStateRequest();
setState.EntityMoniker = new EntityReference("task",
task1.Id);
setState.State = new OptionSetValue(1);
setState.Status = new OptionSetValue(5);
testService.Execute(setState);
JS查询(查询条件是中文需要转符encodeURI(),可关联查询expand是关系名称)
var obj = rest.get("new_shopSet(guid'" + new_original_shopid[0].id
"')?$select=new_ERP,new_account_shop,new_account_new_shop2/new_company_type&$expand=new_account_new_shop2");
var account = Xrm.Page.getAttribute("yto_account");
var rest=new fwREST();
var accountObj =
rest.get("AccountSet?$select=Address1_Name,TerritoryId&$filter=AccountId
eq guid'" + account.getValue()[0].id + "'");
if (accountObj.error != undefined) {
&alert("yto_applytogoods|JS|onchangeAccount|获取客户地址区域失败:"
+ accountObj.error.message.value);
&if (accountObj.length & 0) {
&&Xrm.Page.getAttribute("yto_dealeraddress").setValue(accountObj[0].Address1_Name);
主键:obj[0].名称
Lookup:obj[0].Id;obj[0].LogicalNobj[0].N
判断:obj[0].Id!=null
Optionset:obj[0].名称.V
JS创建业务部门
var rest = new fwREST();
var newBusinessUnit = new Object();
newBusinessUnit.Name = "testBusinessUnit";
newBusinessUnit.ParentBusinessUnitId = new Object();
newBusinessUnit.ParentBusinessUnitId.LogicalName =
"businessunit";
newBusinessUnit.ParentBusinessUnitId.Id =
"{F3A5B2E9-C150-E211-AD82-E0D}";//根部门GPX
var createBusinessJson=JSON.stringify(newBusinessUnit);
var createBusinessResult = rest.create("BusinessUnit",
createBusinessJson);
if (createBusinessResult.error != undefined) {
&alert("Account|JS|createSystemAccount|创建失败:" +
createBusinessResult.error.message.value);
&var newBusinessUnitId =
createBusinessResult.BusinessUnitId;
&alert(newBusinessUnitId);
JS更新客户
var rest = new fwREST();
var newAccount = new Object();
newAccount.new_account_status = new Object();
newAccount.new_account_status.Value = ;
var content=new Object();
content.Id="";
content.LogicalName="";
//content.Name="";
newAccount.content=
newAccount.new_isconfirm =//单选类型
rest.update("Account", id, JSON.stringify(newAccount), function
&if (res.error != undefined) {
&&alert("Account|JS|createSystemAccount|更新失败:"
+ res.error.message.value);
2.服务器复合查询
//根据客户ID获取客户类型
private int GetAccounttypeById(Guid accountId, IOrganizationService
&int yto_accounttype = 0;
&string fetchxml = @"
&&&&&&&&&&
&&&&&&&&&&
&EntityCollection entityCollection =
service.RetrieveMultiple(new Fetchexpression_r(fetchxml));
&foreach (var entity in
entityCollection.Entities)
(entity.Contains("yto_accounttype"))
&&&yto_accounttype
= (entity["yto_accounttype"] as OptionSetValue).V
&return yto_
fetchXML查询的分组和统计
&(((AliasedValue)item["new_bugetid_all"]).Value as
EntityReference)
3.Lookup记录选择窗口完全自定义方式
var lookupViewArgs = {
&&& items:
&&& customViews:
"{F86239AE-C483-E211-B9C3-}",&&&&&&&&&&
//自定义视图ID(随意取)
recordType:
2,&&&&&&&&&&&&&&&&&&&&&&&&&
//实体类型
"TEST",&&&&&&&&&&&&&&&&&&&&&&&&&&
//自定义视图名称
fetchXml: '',
layoutXml: '',
availableViews: null
var url = "";
openStdDlg(url, lookupViewArgs, 800, 500);
4.连接CRM服务器:
using Microsoft.Xrm.C
using Microsoft.Xrm.Sdk.Q
using Microsoft.Xrm.S
using Microsoft.Crm.Sdk.M
CrmConnection connection =
CrmConnection.Parse("Url=http://192.168.2.174/LUsername=Password=Pa$$w0Domain=LIBYCRM;");
CrmOrganizationServiceContext service = new
CrmOrganizationServiceContext(connection);
5.手动执行审批流下一步(fw_action和fw_workflow_directionid[可以不用更新])
Entity fw_wf_user_task = new Entity("fw_wf_user_task");
fw_wf_user_task.Id = entityCollection.Entities[0].Id;
fw_wf_user_task["fw_action"] = new OptionSetValue();
//fw_wf_user_task["fw_workflow_directionid"] = new
EntityReference("fw_workflow_directing", new
Guid("9E9E5C2C-659A-E211-8F62-"));
CrmUtil.OrgServiceContext.Update(fw_wf_user_task);
手动执行审批流JS:
var usertask = new Object();
usertask.fw_action = new Object();
usertask.fw_action.Value =
;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
var direction = new Object();
direction.Id = "9E9E5C2C-659A-E211-8F62-";
direction.LogicalName = "fw_workflow_directing";
usertask.fw_workflow_directionid =
rest.update("fw_wf_user_task", tasks[0].fw_wf_user_taskId,
JSON.stringify(usertask), function (res) {
&if (res.error != undefined) {
&&msg += "单据[" + objs[0].yto_name
+ "]审批失败:" + res.error.message.value + "\n";
&&msg += "单据[" + objs[0].yto_name
+ "]审批成功" + "/n";
6.添加了审批流的实体,在状态变更的时候获取的上下文登陆人是system,根据顶级上下文获取当前真实登陆人:
/// 获取最顶级插件上下文对象
/// 当前插件上下文对象
/// 返回最顶级插件上下文对象
public IPluginExecutionContext
GetTopContext(IPluginExecutionContext currentContext)
&IPluginExecutionContext topContext =
&for (int i = 0; i &= currentContext.D
(topContext.ParentContext!=null)
&&&topContext =
topContext.ParentC
&return topC
8.插件注册管道
验证前:& 数据补充和验证
操作前:& 核心操作前对其他数据进行变更、创建、删除(失败可回滚)
操作后:& 验证数据执行情况,执行核心操作后的后继工作
9.JS返回访问平台
navigator.platform
navigator.userAgent.match(/(iPhone|iPod|Android|ios)/i)
10.JS返回日期间隔
&function dateDiff(interval, date1, date2)
var objInterval = {'D' : 1000 * 60 * 60 * 24, 'H' : 1000 * 60 * 60,
'M' : 1000 * 60, 'S' : 1000, 'T' : 1};
interval = interval.toUpperCase();
var dt1 = Date.parse(date1.replace(/-/g, '/'));
var dt2 = Date.parse(date2.replace(/-/g, '/'));
&&&&&&&&&&&
return Math.round((dt2 - dt1) / eval_r('(objInterval.' + interval +
&&&&&&&&&&&
说明:interval 取值: d (day), m(minutes), s(second), t(毫秒),不分区大小写
日期格式: yyyy (/-) (m)m (/-) (d)d
11.超过6个subgrid不会自动显示数据(onload,参数100)
//刷新MS CRM表单中未自动加载的SubGrid
var refreshSubGridId;
function loadSubGrids(milliSeconds) {
(!milliSeconds) milliSeconds = 1000;
refreshSubGridId = setInterval(refreshSubGrids,
milliSeconds);
function refreshSubGrids() {
blnSuccess =
var subgrids = Xrm.Page.ui.controls.get(function (control, index) {
return control.getControlType() == "subgrid"; });
if (subgrids.length & 4) for (var i = 4; i & subgrids.
i++) subgrids[i].refresh();
blnSuccess =
&&& } catch (e)
(blnSuccess) clearInterval(refreshSubGridId);
12.禁用SubGrid
function disableSubGrid(subGridName) {
var subGrid = document.getElementByIdx_x_x_x(subGridName +
if (subGrid) subGrid.disabled =
&&& } catch (e)
13.创建服务
CrmConnection connection =
CrmConnection.Parse(CRMConnectionPath);
using (CrmOrganizationServiceContext orgservice = new
CrmOrganizationServiceContext(connection))
&AutoShut(orgservice);
14.让报表取到当前表单的ID:
select new_promotionid from filterednew_promotion as
crmaf_filterednew_promotion
select new_name from filterednew_promotion& where
对DS2生成的参数@proid-属性-默认值-DS1
让报表取到当前用户ID:
SELECT [dbo].[fn_FindUserGuid]()
select systemuserid,fullname from FilteredSystemUser where
systemuserid = dbo.fn_FindUserGuid()
让报表取到当前用户ID:
select businessunitid,name from businessunit where businessunitid =
dbo.fn_FindBusinessGuid()
15.执行工作流
ExecuteWorkflowRequest request = new ExecuteWorkflowRequest()
&WorkflowId = new
Guid("C4745DA5-CA92-4E37-9A63-0F3BC73ECB06"),
&EntityId = new
Guid("C68B84F8-D397-E311-93FD-2E")
ExecuteWorkflowResponse response =
(ExecuteWorkflowResponse)testService.OrganizationService.Execute(request);
16.多对对,N对N,添加关系:
EntityReferenceCollection coll=new
EntityReferenceCollection();
coll.Add(new EntityReference("systemuser",new
Guid("1DCCAD1E-9F67-E311-93EF-30")));
testService.Associate("team", new
Guid("99C72A6E-EA71-E311-93FD-2E"), new
Relationship("teammembership_association"), coll);
已存在关系,会报错。
我的更多文章:
( 14:55:05)( 12:30:48)( 10:35:55)( 12:38:49)( 22:23:56)( 13:54:10)
已投稿到:
以上网友发言只代表其个人观点,不代表新浪网的观点或立场。插件是可与 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 EntityR
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 serviceP
public IPluginExecutionC
public IOrganizationServiceF
public IOrganizationS
public String prefix = &new_&;
public String customEntityN
[TestInitialize]
public void GetOrgService()
//跨域调试采用这个URL,同域用http://me-crm-01/crm即可
string server = &Url=http://crmdev:5555/CRM;Domain=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);
下面就进入调试方法了:
(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&, &004&)[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也通过了,但注册完插件,在真实环境里运行时,还是报错,比如像里遇到的错误,这时我们就要用到跟踪功能。
跟踪功能可以提供运行时插件信息,以帮助诊断插件故障的原因,从而帮助开发人员解决插件问题。
此处所说的跟踪不同于 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:
阅读(...) 评论()

我要回帖

更多关于 海康sdk 车辆品牌类型 的文章

 

随机推荐