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

CRM插件实现:任务标记为完成后更新任务记录的问题

CRM Task标记完成后字段更新的Plugin实现问题与解决

问题描述

  • 需求:用户点击「Mark as Complete」将Task的记录状态改为complete时,触发自定义逻辑并更新Task的部分字段
  • 实现思路:因无专门的complete事件,选择在Update消息中通过Plugin检查状态变更
  • 遇到的问题:
    • 直接修改PostEntityImages时,CRM返回错误:The object cannot be updated because it is read-only. If you contact support, please provide the technical details.
    • 使用PreEntityImages可更新字段,但无法获取变更后的statuscode和modifiedon
    • 使用InputParameters中的Target仅能完成状态变更,自定义逻辑未触发

原核心代码片段:

if (context.InputParameters.Contains("Target") && context.InputParameters["Target"] is Entity)
{
    currentTask = (Entity)context.InputParameters["Target"];
    if (currentTask.LogicalName == "task")
    {
        afterUpdateTask = (Entity)context.PostEntityImages["updatedTask"];
        beforeUpdateTask = (Entity)context.PreEntityImages["updatedTask"];
        if (afterUpdateTask.Contains("statuscode"))
        {
            int statuscode = ((OptionSetValue)afterUpdateTask["statuscode"]).Value;

            if (statuscode == 5)
            {
                // 自定义逻辑与字段更新代码
            }
        }
    }
}

解决方案

可以通过Plugin实现,核心是不能直接修改Post/Pre实体图像,需通过OrganizationService重新发起更新操作,步骤如下:

1. 正确注册Plugin

  • 消息:Update
  • 实体:Task
  • 事件管道阶段:Post Operation(同步模式)
  • 勾选Pre Entity Image和Post Entity Image,图像名称统一设置(例如TaskImage,需与代码中引用一致)
  • 筛选条件:可设置仅当statuscode字段变更时触发,减少不必要执行

2. 修正后的核心代码

// 获取上下文与服务
IPluginExecutionContext context = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));
IOrganizationServiceFactory serviceFactory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));
IOrganizationService service = serviceFactory.CreateOrganizationService(context.UserId);

Entity preTask = null;
Entity postTask = null;

// 读取Pre和Post实体图像
if (context.PreEntityImages.Contains("TaskImage"))
    preTask = context.PreEntityImages["TaskImage"];
if (context.PostEntityImages.Contains("TaskImage"))
    postTask = context.PostEntityImages["TaskImage"];

// 验证状态变更:从非Complete变为Complete(statuscode=5)
if (preTask != null && postTask != null)
{
    int preStatus = ((OptionSetValue)preTask["statuscode"]).Value;
    int postStatus = ((OptionSetValue)postTask["statuscode"]).Value;

    // 仅当状态从非5变为5时触发逻辑
    if (preStatus != 5 && postStatus == 5)
    {
        // 创建要更新的Task实体,仅携带需要修改的字段+Id
        Entity taskToUpdate = new Entity("task", postTask.Id);
        // 示例:更新自定义字段或系统字段
        taskToUpdate["new_customfield"] = "标记完成后更新的内容";
        taskToUpdate["description"] = $"任务于{postTask["modifiedon"]}完成"; // 使用Post中的modifiedon

        // 执行更新
        service.Update(taskToUpdate);

        // 此处添加其他自定义逻辑(如关联记录操作、通知等)
    }
}

关键说明

  • PostEntityImages是只读的,仅用于读取变更后的字段值(如statuscode、modifiedon),不能直接修改
  • 必须通过IOrganizationService发起新的Update请求来修改Task字段
  • 添加状态变更的判断(preStatus !=5 && postStatus==5),避免重复触发(例如Task已完成后再修改其他字段时不会重复执行逻辑)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 03:20:30