2011-05-16 49 views
6

在Microsoft Dynamics CRM 4.0中創建插件時,可以使用以下內容來檢查導致插件觸發的事件的來源。如何防止Microsoft Dynamics CRM 2011中沒有ExecutionContext.CallerOrigin的無限循環?

public void Execute(IPluginExecutionContext context) 
    { 
     if (context.CallerOrigin.GetType() == CallerOrigin.WebServiceApi.GetType()) 
     { 
      return; 
     } 
     plugin code here... 
    } 

這將允許你檢查行動是由一個形式的用戶引起的,通過Web服務或工作流程等..

我有一個創建和更新實體同步應用程序通過WCF,並且不希望插件在發生這種情況時執行,只有當用戶編輯實體(以防止同步過程中的無限循環)時。

IExecutionContext.CallerOrigin已在MS Dynamics CRM 2011,中刪除,那麼採用什麼新方法可以做到這一點?

我在想,可能有辦法在WCF調用中設置IExecutionContext.CorrelationId,然後檢查它在插件中的具體GUID,但我還沒有任何運氣。

回答

2

你看過IPluginExecutionContext.InputParameters嗎?

另一種選擇是修改插件,如果沒有任何更改,就不會更新任何內容,這將防止無限循環的可能性。

+0

我可能有,如果變化是由指定的用戶發起的,不更新,因爲會被同步工具的變化。我真的想避免雙重同步,而不是無限循環:)我可以在同步工具 – csjohnst 2011-05-19 06:16:59

+0

context.InitiatingUserId給你的GUID ID停止循環。在我的情況下,我想排除單個用戶從解僱插件,這就做到了。 – kmria 2015-03-18 10:21:52

11

雖然這似乎已經問過一段時間了(我認爲OP已經找到他的解決方案了!)我碰到它最近尋找類似的答案。爲了找到我需要的東西,我花了進一步的研究,因此我也將其添加到其他任何碰到它的人。如果你正在尋找它,這個屬性已經過時了。據說這是因爲它不可靠,但爲什麼我們需要MSCRM 4.0中的CallerOrigin有幾個原因。在另一方面,也有解決這個過時太方式:

防止無限循環(超過2插件)

這就是我一直在尋找的CallerOrigin的原因,我碰到這個問題怎麼來的。如果插件來自表單上的用戶,而不是其他插件(即asyc process/webservice),我只希望該插件能夠觸發。在我的情況下,「超過2個插件」的區別非常重要,因爲我無法使用InputParameters來解決問題。我的例子類似於以下內容:

  • 更新「父」實體的插件。如果在父實體上將稱爲「狀態」的選項集設置爲「已批准」,我隨後希望將所有子實體的狀態設置爲「已批准」。

  • 「兒童」實體更新插件。如果子實體上名爲「狀態」的選項集已設置爲「已批准」,並且同一父級的所有其他子級都將此設置爲「已批准」,則需要更新父級上的狀態以進行批准。

這會導致如果不保護自己免受它的無限循環。您也不能使用InputParameters來解決它。一個基本的解決方案是使用深度檢查:

context.PluginExecutionContext.Depth 

如果它大於1,它會被另一個插件/工作流調用。注意:如果您的工作流正在觸發初始更新,則可能需要小心檢查的是什麼值。從脫機客戶

防止同步問題

我們已經被賦予不同的屬性,以幫助我們區分這些人。使用這些來代替:

context.PluginExecutionContext.IsExecutingOffline 
context.PluginExecutionContext.IsOfflinePlayback 

起反應不同,具體取決於原產地是

好了,所以這是我們確實需要CallerOrigin的唯一方案。我認爲你能做到這一點的唯一方法是檢查PluginExecutionContext本身的類型。我知道異步它的類型:

Microsoft.Crm.Asynchronous.AsyncExecutionContext 

和插件這似乎是:

Microsoft.Crm.Extensibility.PipelineExecutionContext 

不知道它是從外部來的時候,我很遺憾沒有任何代碼目前可用於測試並計算出結果。外面所有的話你可能要檢查的:

PluginExecutionContext.ParentContext 

唯一的其他方法,我已經遇到,用於檢測更新從使用自定義標記的形式來了。所以,你可以創建一個名爲 「OriginOfChange」(或類似的東西)與選項的OptionSet

  • CRM表(使用Javascript的OnSave)
  • 工作流程
  • 插件

然後在更新過程中什麼都會更新實體。通過這種方式,您可以每次檢查輸入參數以查看更新來自哪裏。

如果您需要根據來源採取不同的反應,則最後這種方法最可能最安全。

+2

這是這裏最好的答案,但你的時候,你斷言,如果深度大於一,這個插件是由另外一個插件叫做在技術上是不正確。如果工作流會導致一個插件火,那將具有深度2,如果一系列鏈接在一​​起的工作流程造成火災插件,深度將等於鏈流程的號碼一起+ 1 – 2015-08-31 16:12:35

+0

@JosephDuty謝謝反饋,優點。我會更新這個問題來反映這一點。 – 2015-09-01 11:17:20

+0

要添加到最後2點,我添加了一些額外的細節周圍的插件/工作流程和深度檢查。事後看來(還有幾年的經驗!)我認爲在爲此目的使用深度檢查時可能需要小心。我建議的最後一個方法是最好的(在我看來)使用。我已經將原始答案的癥結留在原地,因爲我認爲它不應該被編輯太多。 – 2015-09-08 10:31:19

3

This線程的解決方案是「只要檢查context.depth財產,如果是大於1倍的回報」

它的工作對我在那裏更新其內的實體我更新的插件完全正常,導致插件被解僱了兩次,但第二次,它檢查了深度並退出。

更新

迄今爲止最安全的方法是使用shared parameters而非雖然插件深度。如果唯一被檢查的是插件深度,那麼隨着另一個插件觸發另一個插件,它將不會執行,因爲它的深度爲2,即使插件第一次爲Update事件觸發。

+0

我一直的印象,這成爲在你有,例如,工作流程或插件更新實體並觸發代碼的情況下不可靠。例如。如果您的插件設計爲將new_fieldA添加到new_fieldB並填充new_fieldTotal,並且它應該在new_fieldA或new_fieldB更改時觸發,則在運行時通過UI更改的Depth是1.我認爲如果另一個插件或工作流更改new_fieldA或new_fieldB觸發你的插件,然後'深度'> 1.我應該測試這個,但我在這裏評論,以防其他人已經有... :) – 2012-09-10 16:18:29

-3

深度執行,而不是遞歸。您的插件第一次執行時,您可以獲得Depth> 1。認爲它是在執行流水線(實際上是執行堆棧深度)一個級別,有一個人得到了它第一,當執行傳遞深度增加1,因此在線路旁邊做一些其他的操作,並再次傳遞之前,到管道增加+1深度,現在Dynamics執行你的插件,你的深度將是3(初始1 [+1 | +1])。 CRM 2011內部部署默認限制爲8,聯機限制爲16深度。

因此,通過使用Depth進行遞歸預防,您只是假設它,您無法斷言它。

MSDN IExecutionContext.Depth Property

我的2美分, 問候 埃裏克Arean

+0

儘管我同意你在技術上是正確的,但你的答案不符合上下文關於所問的問題。如果這是對先前答案的評論,那麼我可能會將其改爲upvoted。 – 2014-02-27 10:04:52