C#脚本组件
C#脚本组件(CSharpScript)用于在流程中执行 C# 代码,实现配置无法覆盖的复杂业务逻辑。
本文档是 平台接口 概念的具体配置说明。建议先阅读平台接口概念,了解整体架构。
概述
当可视化配置无法满足业务需求时,可通过 C# 脚本组件直接编写代码处理业务。组件内嵌代码编辑器,支持语法高亮与智能提示,保存时会调用脚本语法检查接口进行校验,校验通过后才会保存脚本。
配置项
| 配置项 | 说明 |
|---|---|
| CSharp脚本 | 组件执行的 C# 代码,缺省为系统脚本模板,通过代码编辑器弹窗编辑 |
| 输出到最终结果 | 开启后该组件结果作为接口返回值 |
脚本模板
缺省脚本是系统提供的执行入口模板,可在此基础上编写业务逻辑:
using System;
using System.Linq;
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using Chameleon.Common;
using Chameleon.Common.Context;
using Chameleon.Common.Exceptions;
using Chameleon.Common.Models;
using Chameleon.Database;
using Chameleon.SDK;
public class ChameleonCSharpScript
{
public async Task<object> ExecuteAsync(ComponentContext context, ChameleonSDK sdk)
{
// JsonConvert.SerializeObject();
// JsonConvert.DeserializeObject<>();
// sdk.Logger.LogDebug($"this is a log");
// var obj = await sdk.DbContext.GetByIdAsync("system.UserInformation", Guid.Parse("xxx-id"), new[] { "Name" });
return null;
}
}
脚本参数说明
脚本围绕 context 上下文参数进行处理,ExecuteAsync 方法提供以下参数:
| 参数 | 说明 |
|---|---|
| context | 组件上下文对象,包含请求参数、流程数据等,详见 组件上下文说明 |
| sdk | SDK 对象,提供 Logger(日志记录器)和 DbContext(数据库操作上下文)等能力 |
context 常用属性
| 属性 | 说明 |
|---|---|
| Request | 前端请求参数,Result.List 为 List<ObjectData> 类型 |
| DicParam | 字典类型参数,用于在组件间传递数据 |
| Param | 弱类型通用参数,用于在脚本中传递参数 |
| CmpResult | 上游组件的执行结果 |
| Result | 最终响应结果 |
更多 context 详细说明请参考 组件上下文 文档。
使用场景
- 复杂业务逻辑处理
- 数据转换和计算
- 第三方系统集成
- 自定义数据验证
注意事项
- C# 脚本具有较高的执行权限,请谨慎编写,避免安全风险
- 保存脚本时会进行语法检查,校验不通过将无法保存
- 建议在开发环境充分测试后再部署到生产环境
- 复杂逻辑建议封装为独立方法,提高代码可读性
下一步
属性明细
以下内容面向技术实现与 AI 检索,说明 C# 脚本组件的节点元数据。
节点元数据
C# 脚本组件由 FlowCmpType.CSharpScript 标识:
| 属性名 | 类型 | 含义 | 取值/存储值 |
|---|---|---|---|
type | string | 组件类型 | 固定为 "CSharpScript" |
Script | string | C# 脚本内容 | 缺省为系统脚本模板 |
IsFinalResult | string(bool) | 是否输出到最终结果 | "true" / "false" |
order | string | 同级排序 | 例:"1" |
元数据存储示例
{
"ID": "cs1",
"type": "CSharpScript",
"Script": "using System; ... public class ChameleonCSharpScript { ... }",
"IsFinalResult": "true",
"order": "1"
}
相关接口
保存脚本前会调用 POST /api/CSharpScript/SyntaxChecking 进行语法校验,校验通过(code = 200)后保存。
服务端执行逻辑
C# 脚本组件由 CSharpScriptComponentManager(继承 InterfaceComponentManagerBase)实现,组件类型为 FlowComponentTypeEnum.CSharpScript。脚本的编译与执行委托给 ICSharpScriptEngineService(实现类 CSharpScriptEngineService)。
节点
meta中的所有值均以字符串存储,服务端统一通过SafeGet("Key")读取字符串。
执行时机与场景
脚本在组件校验期与执行期各调用一次引擎:校验期做危险代码与语法编译检查,执行期真正运行脚本。适用于可视化配置无法覆盖的定制业务逻辑。
输入参数(meta 键)
| 键 | 读取方式 | 含义 |
|---|---|---|
Script | meta.SafeGet("Script") | C# 脚本内容,空脚本直接返回 null |
IsFinalResult | meta.SafeGet("IsFinalResult") | "true" 时脚本返回值写入 context.Result |
IsDisabled | meta.SafeGet("IsDisabled") == "true" | 为 true 时跳过本组件 |
执行步骤
- 校验期
_VerifyAsync:读取Script→ 调用VerifyInterfaceComponentAsync:- 空脚本直接通过;
- 由
InvalidCSharpScriptVerifyHelper.VerifyDangerousCode做危险代码检查; - 以
ClassFullName = "ChameleonCSharpScript"、Parameters = [context, sdk]构造DynamicScript,调用cSharpScriptEngine.CheckScript做语法编译校验。
- 执行期
_ExecuteAsync:读取Script→ 调用ExecuteInterfaceComponentAsync:- 通过脚本文本是否包含
async Task<object> ExecuteAsync判定入口方法名(ExecuteAsync或Execute); - 异步脚本走
cSharpScriptEngine.ExecuteAsync<object>,同步脚本走Execute<object>; - 方法参数注入
ComponentContext context与ChameleonSDK sdk,返回result.Data。
- 通过脚本文本是否包含
- 将结果写入
context.CmpResult = result。 meta.SafeGet("IsFinalResult")为"true"时context.Result = result。- 调用
ExecuteNextAsync继续下游。
输出与上下文
| 字段 | 说明 |
|---|---|
context.CmpResult | 脚本返回值,供下游组件读取 |
context.Result | 仅 IsFinalResult = "true" 时写入脚本返回值 |
脚本内可直接读写 context(Request、DicParam、Param、AndFilter、MouFilter、FilterOverride 等)与 sdk(Logger、DbContext);返回 null 表示不改变链路结果。字段详情见 组件上下文。
权限、安全与限制
- 危险代码黑名单(不区分大小写)会拒绝包含以下内容的脚本:
Process.、Directory.、Assembly.、unsafe、static void Main、File.、Path.、FileStream、FileInfo、DirectoryInfo、System.Reflection、System.Diagnostics、System.Environment、AppDomain.、DllImport.、PInvoke.。 - 自定义黑名单:脚本中出现
ChameleonAppSettingConfig或appsettings字样同样被拒绝。 - 脚本拥有较高执行权限,需谨慎编写,避免安全风险。
- 校验失败时抛出组件校验失败异常,
PopType为通知。