標籤:crm 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方法,外掛程式的邏輯就可以在這裡實現了。
1: public class new_marketing_plan_updatePost : IPlugin
2: {
3: public void Execute(IServiceProvider serviceProvider)
4: {
5: IPluginExecutionContext context = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));
6:
7: //檢查實體名稱
8: if (context.PrimaryEntityName.ToLower() != "new_marketing_plan")
9: {
10: throw new InvalidPluginExecutionException("Entity is not Marketing Plan");
11: }
12: // 檢查訊息是否正確
13: if (context.MessageName.ToLower() != "update")
14: {
15: throw new InvalidPluginExecutionException("message is not Update");
16: }
17:
18: if (context.InputParameters.Contains("Target") && context.InputParameters["Target"] is Entity)
19: {
20: Entity entity = (Entity)context.InputParameters["Target"];
21: IOrganizationServiceFactory serviceFactory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));
22: IOrganizationService userService = serviceFactory.CreateOrganizationService(context.UserId);
23: IOrganizationService adminSerivce = serviceFactory.CreateOrganizationService(null);
24:
25: DoAction(adminSerivce, userService, entity);
26: }
27: }
28: }
二、刪除外掛程式
根據上面的介紹,擷取當前實體的時是用的這種方式:
1: Entity entity = (Entity)context.InputParameters["Target"];
但是對於刪除事件,就不能這樣擷取了,這時應該通過下面的方式來擷取:
1: EntityReference er = context.InputParameters["Target"] as EntityReference;
2: CurrentEntity = new Entity(er.LogicalName);
3: 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 行 )
1: public IServiceProvider serviceProvider;
2: public IPluginExecutionContext context;
3: public IOrganizationServiceFactory factory;
4: public IOrganizationService service;
5: public String prefix = "new_";
6: public String customEntityName;
7:
8: [TestInitialize]
9: public void GetOrgService()
10: {
11: //跨域調試採用這個URL,同域用http://me-crm-01/crm即可
12: string server = "Url=http://crmdev:5555/CRM;Domain=xxx;Username=crmtest02;Password=abc-123";
13:
14: var myConnection = CrmConnection.Parse(server);
15:
16: serviceProvider = MockRepository.GenerateMock<IServiceProvider>();
17: context = MockRepository.GenerateMock<IPluginExecutionContext>();
18: factory = MockRepository.GenerateMock<IOrganizationServiceFactory>();
19: service = MockRepository.GenerateMock<IOrganizationService>();
20: service = new OrganizationService(myConnection);
21: }
4. 調試
下面就進入調試方法了:
(1)類比一個Entity當作觸發外掛程式的實體 (4- 13行 )
(2)直接調試外掛程式裡的DoAction方法 (15-16 行 )
1: [TestMethod]
2: public void TestApproePaymentrequest()
3: {
4: ParameterCollection paramBag = new ParameterCollection();
5:
6: XRMHelper helper = new XRMHelper(service);
7: Entity currentent = helper.GetInfoByAttrValue("new_marketing_plan", "new_name", "20140910-000004")[0];
8: paramBag.Add("Target", currentent);
9:
10: context.Stub(x => x.InputParameters).Return(paramBag);
11: serviceProvider.Stub(x => x.GetService(typeof(IPluginExecutionContext))).Return(context);
12: serviceProvider.Stub(x => x.GetService(typeof(IOrganizationServiceFactory))).Return(factory);
13: factory.Stub(x => x.CreateOrganizationService(null)).Return(service);
14:
15: new_marketing_plan_updatePost mp = new new_marketing_plan_updatePost();
16: mp.DoAction(service, service, currentent);
17: }
四、 日誌記錄和跟蹤
有時外掛程式寫好了,Unit Test也通過了,但註冊完外掛程式,在真實環境裡運行時,還是報錯,比如像Dynamic CRM 2013學習筆記(-)外掛程式輸入實體參數解析裡遇到的錯誤,這時我們就要用到跟蹤功能。
跟蹤功能可以提供運行時外掛程式資訊,以協助診斷外掛程式故障的原因,從而協助開發人員解決外掛程式問題。
此處所說的跟蹤不同於 ASP.NET 跟蹤。跟蹤是在 Microsoft Dynamics CRM SDK 中通過使用Tracing Service ITracingService 而實施的。開發人員在外掛程式代碼中添加 Trace 語句,然後構建並部署外掛程式。在執行過程中,只有當外掛程式在運行時向平台傳回異常時,使用者才會看到跟蹤資訊。對於同步註冊外掛程式,跟蹤資訊會顯示在 Microsoft Dynamics CRM Web 應用程式的對話方塊中。對於非同步註冊外掛程式,跟蹤資訊會顯示在 Web 應用程式中“系統作業”表單的“詳細資料”地區中。此類資訊的數量和特點將取決於開發人員為外掛程式編寫的代碼。
實施此類型跟蹤的主要原因是為了支援 Microsoft Dynamics CRM 中的隔離(沙箱)外掛程式和自訂工作流程活動功能。沙箱自訂代碼無法將資訊寫入到系統事件日誌或檔案系統中。通過實施Tracing Service,就為沙箱外掛程式和自訂工作流程活動提供了一種在拋出異常時輸出運行時資訊的方法。此外,非沙箱外掛程式也支援跟蹤功能。
用法:
(1) 初始化
1: ITracingService tracingService = (ITracingService)serviceProvider.GetService(typeof(ITracingService));
(2) 添加Trace語句
1: tracingService.Trace("In DoAction method");
實際上,我們可以在每個方法裡try catch一下,這下可以快速定位到是哪個方法報錯,再通過Trace語句來精確定位。
例如:
1: catch (Exception ex)
2: {
3: throw new InvalidPluginExecutionException("GetQueryExpression error : " + ex.Message);
4: }
下面是我的一個真實的case:
Dynamic CRM 2013學習筆記 系列匯總
Dynamic CRM 2013學習筆記(二)外掛程式基本用法及調試