You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Dynamics 365中CodeActivity与Plugin通过SharedVariables传值失效问题咨询

问题分析与解决方案

首先得明确你遇到的核心问题:你在CodeActivity里把MyUniqueKey加到了工作流的执行上下文里,但当你通过组织服务创建Quote时,这个Create操作会触发一个完全独立的插件执行上下文——它和工作流的上下文没有父子层级关系,所以你遍历ParentContext根本找不到那个SharedVariable,这就是foundKey一直为false的原因。

下面给你几个可行的解决思路,按推荐程度排序:

方案一:给Quote添加自定义标记字段(最可靠、灵活)

这是最通用的解决方案,原理是直接在你创建的Quote实体上打上标记,插件通过检查这个标记来决定是否执行:

  1. 先在Dynamics 365中给Quote实体新建一个布尔类型的自定义字段,比如new_createdbycodeactivity(显示名可以叫“由代码活动创建”),设置默认值为false。
  2. 修改你的CodeActivity,在创建Quote的时候把这个字段设为true:
protected override void Execute(CodeActivityContext executionContext)
{
    var workflowContext = executionContext.GetExtension<IWorkflowContext>();
    var serviceFactory = executionContext.GetExtension<IOrganizationServiceFactory>();
    var service = serviceFactory.CreateOrganizationService(workflowContext.UserId);

    // 创建Quote实体
    var newQuote = new Entity("quote");
    // 其他必填字段赋值...
    newQuote["new_createdbycodeactivity"] = true; // 打上标记

    service.Create(newQuote);
}
  1. 在你的插件里检查这个标记,满足条件就跳过执行:
public void Execute(IServiceProvider serviceProvider)
{
    var context = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));
    
    if (context.MessageName == "Create")
    {
        var quoteTarget = (Entity)context.InputParameters["Target"];
        // 检查标记字段,如果存在且为true,就跳过插件逻辑
        if (quoteTarget.Contains("new_createdbycodeactivity") && 
            (bool)quoteTarget["new_createdbycodeactivity"])
        {
            // 可选:如果不需要保留标记,可以在这里把字段改回false
            // quoteTarget["new_createdbycodeactivity"] = false;
            return;
        }
        
        // 你的正常插件逻辑...
    }
}

方案二:利用插件上下文的Depth属性(适合简单场景)

如果你的场景中,只有这个CodeActivity会通过嵌套调用创建Quote,那么可以通过Depth属性判断:

  • 工作流的执行上下文Depth是1,它调用Create Quote生成的插件上下文Depth是2
  • 手动创建Quote时,插件上下文Depth是1

修改插件代码:

public void Execute(IServiceProvider serviceProvider)
{
    var context = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));
    
    if (context.MessageName == "Create")
    {
        // 如果是嵌套调用(Depth>1),就跳过执行
        if (context.Depth > 1)
        {
            return;
        }
        
        // 你的正常插件逻辑...
    }
}

⚠️ 注意:这个方法有局限性,如果其他业务场景也会有嵌套创建Quote的情况(比如另一个插件创建Quote),会误阻止那些场景的插件执行。

方案三:通过自定义请求头部传递标记(进阶方案)

如果你不想修改实体结构,可以通过组织服务的自定义头部传递标记:

  1. 修改CodeActivity,创建组织服务时添加自定义头部:
protected override void Execute(CodeActivityContext executionContext)
{
    var workflowContext = executionContext.GetExtension<IWorkflowContext>();
    var serviceFactory = executionContext.GetExtension<IOrganizationServiceFactory>();
    var service = (OrganizationServiceProxy)serviceFactory.CreateOrganizationService(workflowContext.UserId);
    
    // 添加自定义头部
    service.HeaderToken["MyUniqueKey"] = "MyValue";

    // 创建Quote实体
    var newQuote = new Entity("quote");
    // 其他字段赋值...
    service.Create(newQuote);
}
  1. 在插件里读取这个自定义头部:
public void Execute(IServiceProvider serviceProvider)
{
    var context = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));
    var serviceFactory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));
    var service = (OrganizationServiceProxy)serviceFactory.CreateOrganizationService(context.UserId);
    
    if (context.MessageName == "Create")
    {
        // 检查自定义头部
        if (service.HeaderToken.ContainsKey("MyUniqueKey") && 
            service.HeaderToken["MyUniqueKey"].ToString() == "MyValue")
        {
            return;
        }
        
        // 你的正常插件逻辑...
    }
}

⚠️ 注意:这个方法需要确保组织服务的代理类型正确,而且头部只在当前服务实例的请求中有效,适合复杂但不想修改实体的场景。


内容的提问来源于stack exchange,提问作者Equalsk

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.13 09:20:40