如何在Microsoft Dynamics CRM 2011中没有ExecutionContext.CallerOrigin的情况下阻止无限循环?

csj*_*nst 6 c# wcf dynamics-crm infinite-loop dynamics-crm-2011

在Microsoft Dynamics CRM 4.0中创建插件时,您可以使用以下内容检查导致插件触发的事件的来源.

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

这将允许您检查操作是由表单中的用户,Web服务还是工作流等引起的...

我有一个同步应用程序,它通过WCF创建和更新实体,并且不希望插件在发生这种情况时执行,只有当用户编辑实体时(以防止同步过程中出现无限循环).

IExecutionContext.CallerOrigin已在MS Dynamics CRM 2011中删除,那么新的方法是什么?

我当时认为可能有一种方法可以设置IExecutionContext.CorrelationIdWCF调用,然后检查插件中的特定Guid,但我还没有运气.

Con*_*her 11

虽然这似乎已被问到一段时间了(我认为OP现在已经找到了他的解决方案!)我最近发现它寻找类似的答案.我需要进一步的研究才能找到我需要的东西,因此我也会在这里为其他任何人添加它.

首先,如果您正在寻找它,这家酒店已经过时了.据说是因为它不可靠,但我们需要在MSCRM 4.0中使用CallerOrigin的原因有几个.另一方面,有一些方法可以解决这个问题:

防止无限循环(超过2个插件)

这就是我寻找CallerOrigin以及我是如何遇到这个问题的原因.我只想要插件来自表单上的用户,而不是来自其他插件(即asyc进程/ webservice).在我的情况下,它是"超过2个插件"的区别是非常重要的,因为我不能使用InputParameters来解决问题.我的例子类似于以下内容:

  • 更新"父"实体的插件.如果父实体上名为"状态"的选项集设置为"已批准",我随后又想将所有子实体的状态设置为"已批准".

  • 更新"Child"实体的插件.如果子实体上名为"Status"的选项集设置为"已批准",并且同一父级的所有其他子级都将此设置为"已批准",则我还需要将父级上的状态更新为已批准.

如果您不保护自己不受此限制,则会导致无限循环.您也无法使用InputParameters来解决它.一个基本的解决方案是使用深度检查:

context.PluginExecutionContext.Depth
Run Code Online (Sandbox Code Playgroud)

如果大于1,则由另一个插件/工作流调用.注意:如果您的工作流程正在触发初始更新,则可能需要注意要检查的值.

防止脱机客户端同步问题

我们被赋予了不同的属性来帮助我们区分这些属性.请改用:

context.PluginExecutionContext.IsExecutingOffline
context.PluginExecutionContext.IsOfflinePlayback
Run Code Online (Sandbox Code Playgroud)

根据原点的不同,做出不同的反应

好的,所以这是我们确实需要CallerOrigin的唯一场景.我认为你能做到这一点的唯一方法是检查PluginExecutionContext本身的类型.我知道异步它的类型:

Microsoft.Crm.Asynchronous.AsyncExecutionContext
Run Code Online (Sandbox Code Playgroud)

对于插件,它似乎是:

Microsoft.Crm.Extensibility.PipelineExecutionContext
Run Code Online (Sandbox Code Playgroud)

不确定来自外部来源的是什么,遗憾的是我目前没有任何可用的代码来测试和解决这个问题.除了你可能需要检查的所有内容之外:

PluginExecutionContext.ParentContext
Run Code Online (Sandbox Code Playgroud)

我遇到的另一种检测更新来源的方法是在表单上使用自定义标志.因此,您可以使用选项创建名为"OriginOfChange"(或类似的东西)的OptionSet

  • CRM表格(Javascript onsave)
  • 工作流程
  • 插入
  • 等等

然后更新实体在更新期间设置此字段.通过这种方式,您可以每次检查输入参数以查看更新的来源.

如果您需要根据来源做出不同的反应,最后一种方法很可能是最安全的.

  • 这是最好的答案,虽然你断言如果深度大于1,技术上是不正确的,这个插件被另一个插件调用.如果工作流导致插件触发,其深度为2,如果链接在一起的一系列工作流导致插件触发,则深度将等于链接在一起的工作流的数量+ 1. (2认同)

小智 2

您查看过 IPluginExecutionContext.InputParameters 内部吗?

另一种选择是修改您的插件,使其在没有更改的情况下不更新任何内容,这将防止无限循环的可能性。