惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

B
Blog RSS Feed
D
Darknet – Hacking Tools, Hacker News & Cyber Security
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
G
Google Developers Blog
MyScale Blog
MyScale Blog
Google DeepMind News
Google DeepMind News
J
Java Code Geeks
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
C
Check Point Blog
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
P
Proofpoint News Feed
D
Docker
Jina AI
Jina AI
博客园 - 三生石上(FineUI控件)
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
Help Net Security
Help Net Security
Google DeepMind News
Google DeepMind News
L
LINUX DO - 最新话题
T
Tailwind CSS Blog
N
Netflix TechBlog - Medium
Forbes - Security
Forbes - Security
MongoDB | Blog
MongoDB | Blog
Attack and Defense Labs
Attack and Defense Labs
Webroot Blog
Webroot Blog
A
About on SuperTechFans
Schneier on Security
Schneier on Security
Hacker News - Newest:
Hacker News - Newest: "LLM"
Microsoft Azure Blog
Microsoft Azure Blog
F
Fortinet All Blogs
IT之家
IT之家
The Last Watchdog
The Last Watchdog
腾讯CDC
Microsoft Security Blog
Microsoft Security Blog
Project Zero
Project Zero
B
Blog
Recorded Future
Recorded Future
博客园_首页
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
S
SegmentFault 最新的问题
Security Archives - TechRepublic
Security Archives - TechRepublic
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
H
Hacker News: Front Page
T
Threatpost
H
Heimdal Security Blog
Cloudbric
Cloudbric
Google Online Security Blog
Google Online Security Blog
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
V
V2EX
云风的 BLOG
云风的 BLOG
V
Visual Studio Blog

博客园 - Hey,Coder!

Elasticsearch ILM 与 Data Stream 概念及实例说明文档 portainer httphelper封装 Ocelot + Consul + SignalR 粘性会话 正交软件架构 docker postgresql17 主从复制 rabbitmq总结与c#示例 docker rabbitmq quartz dashboard docker consul registrator 服务自动注册consul 微服务动态扩容 ubuntu24.04 安装docker RAG 检索增强生成 软考 - 架构设计师 知识点总结 c# MailKit3.4.3 发送邮件、附件 nginx 反向代理postgresql c# 信号量 xp密钥 c# System.Text.Json 反序列化Dictionary<string,object>时未转换基础类型的处理方法 docker配置代理 openclaw 接入 LMStudio的模型服务 wpf canvas 移动 缩放 windows平台openclaw搭建 wpf scrollerview触摸滚动 c# 动态切换sqlsugar连接字符串 c# Elastic.Clients.Elasticsearch 动态查询 c# es 封装Elastic.Clients.Elasticsearch c# scrollerview滚动到指定元素位置 WPF 重写Expander 基于elsa工作流封装一套变量、组件的体系 常用活动重写 DynamicExpresso 轻量级动态表达式库 c# elsa 3.5.2 程序化工作流常用功能及自定义中间件 leaflet docker 连接老版本的sqlserver ssl错误 c# quartz 动态创建任务 控制任务运行和停止 依赖注入 cefsharp 模拟点击 批量重置数据库的数据 docker 复制远程镜像本地并创建容器 c# newtonsoft dynamic
elsa 3.5 中间件记录最后执行的节点数据
Hey,Coder! · 2026-05-12 · via 博客园 - Hey,Coder!

获取最后执行的节点信息

 public class WorkflowCompletionMiddleware : IWorkflowExecutionMiddleware
 {
     private readonly WorkflowMiddlewareDelegate _next;

     public WorkflowCompletionMiddleware(WorkflowMiddlewareDelegate next)
     {
         this._next = next;
     }

     public async ValueTask InvokeAsync(WorkflowExecutionContext context)
     {
         try
         {
             // 调用下一个中间件
             await _next(context);
         }
         catch (System.Exception)
         {
             //TODO 记录异常日志
             //TODO 更新流程执行异常状态

         }

         //记录流程执行结果
         if (context.Status == WorkflowStatus.Finished)
         {
             var vari = context.Workflow.Variables.ToList();
             var result = context.Variables.ToList();

             var instanceId = context.Id;
             var status = (int)context.SubStatus;

             //此处需要根据实际情况将公共的最外层的流程去掉,只保留业务相关的实际节点
             var lastNode = context.ExecutionLog.LastOrDefault(f => f.ActivityType != "Elsa.Workflow" && f.ActivityType != "Elsa.Flowchart");
             if (lastNode == null)
             {
                 return;
             }

             var activityID = lastNode.ActivityId;
             var activityName = lastNode.ActivityName;

             long startTime = 0;
             long endTime = 0;
             if (lastNode.EventName == "Completed")
             {
                 endTime = lastNode.Timestamp.ToUnixTimeMilliseconds();

                 var startNode = context.ExecutionLog.FirstOrDefault(f => f.ActivityId == lastNode.ActivityId && f.EventName == "Started");
               
                 if (startNode != null)
                 {
                     startTime = startNode.Timestamp.ToUnixTimeMilliseconds();
                 }
             }
             else
             {
                 startTime = lastNode.Timestamp.ToUnixTimeMilliseconds();
             }
         }
     }
 }

记录所有的变量数据

通过定义一个输出变量将所有数据返回,考虑到unicode、特殊字符等问题将数据json之后再base64处理

  var vari = context.Workflow.Variables.ToList();
  var result = context.Variables.ToList();
  var sugar = context.GetService<ISqlSugarClient>();


  var dic = new Dictionary<string, object>();
  foreach (var item in vari)
  {
      var v = JsonConvert.SerializeObject(item.Value);
      dic.Add(item.Name, item.Value);
  }

  var json = JsonConvert.SerializeObject(dic);
  var plainTextBytes = Encoding.UTF8.GetBytes(json);
  var base64Str = Convert.ToBase64String(plainTextBytes);
  context.Output.Add("Out__Result", base64Str);