@
目录- 技术交流QQ群:272729176
- 1. 背景介绍
- 2. 框架组件
- 3. 组件全局注册及使用
- 4. 数据库链接字符串全局配置及使用
- 5. 请求安全及路由配置
- 6. Filter语法说明
- 7. 自定义组件及扩展
- 8. LowcodeCode框架扩展方法
- 技术交流QQ群:272729176
技术交流QQ群:272729176
1. 背景介绍
- 为了您能够更好的“理解、使用”LowcodeCore开发框架,本文主要介绍LowcodeCore框架所有包含的组件及详细的配置说明。
- 如果您是首次认识LowcodeCore框架,建议您先阅读本栏目中的另一篇文章:LowcodeCore 低代码开发框架——快速搭建数据操作API、数据中台
- LowcodeCore.Api.Demo下载
2. 框架组件
2.1 组件列表
LowcodeCore框架中自带多种数据操作组件,后续会持续丰富组件。当前框架中已发布的组件如下:
- 获取HttpContext参数:LowcodeCore.ComponentParts.HttpContextStart
- 接口返回:LowcodeCore.ComponentParts.HttpContextEnd
- 新增数据:LowcodeCore.ComponentParts.DataOperate.DataInsert
- 修改数据:LowcodeCore.ComponentParts.DataOperate.DataUpdate
- 删除数据:LowcodeCore.ComponentParts.DataOperate.DataDelete
- 查询所有数据:LowcodeCore.ComponentParts.DataOperate.DataSelect
- 查询满足条件的第一条数据:LowcodeCore.ComponentParts.DataOperate.DataFirst
- 数据记录总数统计:LowcodeCore.ComponentParts.DataOperate.DataCount
- 判断记录是否存在:LowcodeCore.ComponentParts.DataOperate.DataAny
- 分页查询:LowcodeCore.ComponentParts.DataOperate.TurnPageQuery
- 存储过程执行:LowcodeCore.ComponentParts.DataOperate.ProcedureExecute
- 存储过程查询:LowcodeCore.ComponentParts.DataOperate.ProcedureQuery
2.2 组件配置规则说明
- 组件配置采用JSON格式;由多个组件组成一个API的调用管道;不同组件之间会读取数据,也可以输出数据;不同组件之间的数据交互基于System.Text.Json.Nodes类实现;输出组件数据时,需要指定“变量名称”,使用其他组件数据采用“$.变量名称”的格式;
- 一个完整的API接口配置,必须包含“组件管道配置”和“路由配置”;“组件管理配置”用于构建后台API接口的执行过程,比如:参数采集、数据查询、数据输出;“路由配置”用于指定对外提供服务的API接口URL地址和请求协议(GET、POST);
2.3 组件管道配置说明
- 一个可以输出数据的API组件管道配置,必须包含“Start”节点和“End”节点,如:
{
"ID": "3D24CC45-AE39-43C2-8773-E14C99C903FC",
"Start": {
"Component": "LowcodeCore.ComponentParts.HttpContextStart",
"Parameters": {
"Output": "HttpContext"
},
"Next": "End"
},
"End": {
"Component": "LowcodeCore.ComponentParts.HttpContextEnd",
"Parameters": {
"Response": "$.HttpContext"
}
}
}
说明:
- 上述DEMO中有两个节点:Start、End。
- “Start”节点执行完成,如果需要输出参数,可以自定义“Output”变量名称,供后续节点使用;Output的数据会跟随当前请求的全生命周期存在,后续任何一个节点都可以以“$.变量名”的形式访问;
- “Next”配置表示“Start”执行完成后,下一个需要执行的节点名称。
- 在“End”节点中,“Response”配置值 "$.HttpContext" 表示从全局缓存中获取“Start”节点缓存的变量值;结果会以JSON格式输出;
- 多个不同“组件管道配置”文件中的“ID”值需保持唯一;可赋值为Guid。
- 每个节点配置的固定格式为:
{
"Component": "LowcodeCore.ComponentParts.HttpContextStart",
"Parameters": {
},
"Next": "DataSelect"
}
节点名称 | 是否必须 | 功能描述 |
---|---|---|
Component | 是 | 定义当前节点组件程序集反射路径 |
Parameters | 是 | 定义当前节点组件所支持的参数配置 |
Next | 否 | 定义当前节点执行完成后,下一个执行的节点名称。若当前节点为最后节点,则无需指定Next值。 |
- 例如:“通过URL传参,删除UserCode=001的数据记录,并返回影响数据行”场景,配置结构为:
{
"ID": "8E31B400-A862-4D91-B574-B6A9096CECF0",
"Start": {
"Component": "LowcodeCore.ComponentParts.HttpContextStart",
"Parameters": {
"Output": "HttpContext"
},
"Next": "DataDelete"
},
"DataDelete": {
"Component": "LowcodeCore.ComponentParts.DataOperate.DataDelete",
"Parameters": {
"Entity": {
"ConnectionString": "Data Source=.\\SQL2019; Initial Catalog=Lowcode; Persist Security Info=True; User ID=sa; Password=123456;",
"Name": "Users"
},
"Filter": "{ \"UserCode\":\"$.HttpContext.Query.UserCode\" }",
"IncludeAll": false,
"LimitCount": 1,
"Output": "UsersDeleteCount"
},
"Next": "End"
},
"End": {
"Component": "LowcodeCore.ComponentParts.HttpContextEnd",
"Parameters": {
"Response": "$.UsersDeleteCount"
}
}
}
- 配置中定义了“Start、DataDelete、End”三个执行节点;
- “Start节点”:使用组件“LowcodeCore.ComponentParts.HttpContextStart”采集URL参数,并将参数信息输出到全局变量“HttpContext”中,并指定下一个执行节点为“DataDelete”;
- “DataDelete”节点:使用组件“LowcodeCore.ComponentParts.DataOperate.DataDelete”执行数据删除动作;数据过滤参数"Filter"中使用“$.HttpContext.Query.UserCode”获取“Start”节点输出的“URL参数UserCode”;执行完成后,将结果输出到“UsersDeleteCount”全局变量内;并指定下一个执行节点名称为“End”;
- “End”节点:使用组件“LowcodeCore.ComponentParts.HttpContextEnd”执行数据输出动作,并将“$.UsersDeleteCount”变量值输出到 HttpContext.Response.Write对象。
2.4 获取HttpContext参数
- 组件程序集:LowcodeCore.ComponentParts.HttpContextStart
JSON格式如下:
{
"Component": "LowcodeCore.ComponentParts.HttpContextStart",
"Parameters": {
"Output": "HttpContext",
"FileSaveDir": ""
},
"Next": "End"
}
节点名称 | 是否必须 | 功能描述 |
---|---|---|
Output | 是 | 定义组件输出全局变量参数名称 |
FileSaveDir | 否 | 定义文件上传保存目录。“相对/绝对”路径 |
- 使用全局变量
如:从全局变量名配置为 "Output": "HttpContext"中,获取Url参数“usercode”值(区分大小写)
请求DEMO | 获取参数 | 输出值 |
---|---|---|
http://[domain.com]?usercode=001 | $. HttpContext.Query.usercode | 001 |
http://[domian.com]?usercode=001&usercode=002 | $. HttpContext.Query.usercode | 001,002 |
注:当同名参数存在多个值时,调试值为:"001","002",非 "001,002"。
2.4.1 HttpContext.Url参数
2.4.2 HttpContext.Headers参数
- $.HttpContext.Headers
- $.HttpContext.Headers.User-Agent
2.4.3 HttpContext.Cookies参数
- $.HttpContext.Cookies
- $.HttpContext.Cookies.UserName
2.4.4 HttpContext.Form参数
Method: POST
Content-Type: application/x-www-form-urlencoded
或
Content-Type: multipart/form-data
- $.HttpContext.Form
- $.HttpContext.Form.UserName
2.4.5 HttpContext.FromBody(application/json)参数
Method: POST
Content-Type: application/json
-
$.HttpContext.FromBody
-
$.HttpContext.FromBody.UserName
2.4.6 HttpContext.Form.Files参数(文件上传)
Method: POST
Content-Type: multipart/form-data
<html>
<head>
<title></title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>
<body>
<form action="http://localhost:7172/Lowcode/Demo" method="post" target="_blank" enctype="multipart/form-data">
<input name="UserName" value="张三" />
<input name="UserCode" value="001" />
<input type="file" name="fileupload" value="文件上传" />
<input type="submit" value="提交"/>
</form>
</body>
</html>
-
$.HttpContext.Form
-
$.HttpContext.Form.Files
-
$.HttpContext.Form.Files.fileupload
注:未指定“FileSaveDir”参数时,文件默认保存在站点跟目录“UploadFiles”文件夹下
"Parameters": {
"Output": "HttpContext",
"FileSaveDir": ""
}
2.5 接口返回
- 组件程序集:LowcodeCore.ComponentParts.HttpContextEnd
- JSON格式如下:
{
"Component": "LowcodeCore.ComponentParts.HttpContextEnd",
"Parameters": {
"Response": "$.HttpContext"
}
}
节点名称 | 是否必须 | 功能描述 |
---|---|---|
Response | 否 | 定义“HttpContext.Response.Write”输出指定全局变量参数值 。 不填时,输出:{"success":true} |
2.6 新增数据
- 组件程序集:LowcodeCore.ComponentParts.DataOperate.DataInsert
- JSON格式如下:
{
"Component": "LowcodeCore.ComponentParts.DataOperate.DataInsert",
"Parameters": {
"Entity": {
"ConnectionString": "Data Source=.\\SQL2019; Initial Catalog=Lowcode; Persist Security Info=True; User ID=sa; Password=123456;",
"Name": "Users"
},
"Fields": {
"Id": "$.HttpContext.FromBody.Id",
"Sex": "$.HttpContext.FromBody.Sex",
"UserCode": "$.HttpContext.FromBody.UserCode",
"UserName": "$.HttpContext.FromBody.UserName"
},
"Output": "UsersInsertCount"
},
"Next": "End"
}
节点名称 | 是否必须 | 功能描述 |
---|---|---|
Entity.ConnectionString | 是 | 数据库连接字符串 |
Entity.Name | 是 | 表名 |
Fields | 是 | 表字段赋值。支持“$.变量”取值 |
Output | 否 | 数据影响行数输出到公共变量的变量名称。数据结构:{"AffectedRows":1} |
2.7 修改数据
- 组件程序集:LowcodeCore.ComponentParts.DataOperate.DataUpdate
- JSON格式如下:
{
"Component": "LowcodeCore.ComponentParts.DataOperate.DataUpdate",
"Parameters": {
"Entity": {
"ConnectionString": "Data Source=.\\SQL2019; Initial Catalog=Lowcode; Persist Security Info=True; User ID=sa; Password=123456;",
"Name": "Users"
},
"Fields": {
"Sex": "$.HttpContext.FromBody.Sex",
"UserCode": "$.HttpContext.FromBody.UserCode",
"UserName": "$.HttpContext.FromBody.UserName"
},
"Filter": "{ \"Id\":\"$.HttpContext.Query.Id\" }",
"IncludeAll": false,
"LimitCount": 1,
"Output": "UsersUpdateCount"
},
"Next": "End"
}
节点名称 | 是否必须 | 功能描述 |
---|---|---|
Entity.ConnectionString | 是 | 数据库连接字符串 |
Entity.Name | 是 | 表名 |
Fields | 是 | 表字段赋值 |
Filter | 否 | 过滤条件。支持“$.变量”取值。(详细语法见“Filter语法说明”) |
IncludeAll | 否 | 是否作用于满足条件的所有数据。默认:false |
LimitCount | 否 | 作用于满足条件的指定数据行数。当"IncludeAll=true"时有效。默认:1 |
Output | 否 | 数据影响行数输出到公共变量的变量名称。数据结构:{"AffectedRows":1} |
2.8 删除数据
- 组件程序集:LowcodeCore.ComponentParts.DataOperate.DataDelete
- JSON格式如下:
{
"Component": "LowcodeCore.ComponentParts.DataOperate.DataDelete",
"Parameters": {
"Entity": {
"ConnectionString": "Data Source=.\\SQL2019; Initial Catalog=Lowcode; Persist Security Info=True; User ID=sa; Password=123456;",
"Name": "Users"
},
"Filter": "{ \"Id\":\"$.HttpContext.Query.Id\" }",
"IncludeAll": false,
"LimitCount": 1,
"Output": "UsersDeleteCount"
},
"Next": "End"
}
节点名称 | 是否必须 | 功能描述 |
---|---|---|
Entity.ConnectionString | 是 | 数据库连接字符串 |
Entity.Name | 是 | 表名 |
Filter | 否 | 过滤条件。支持“$.变量”取值。(详细语法见“Filter语法说明”) |
IncludeAll | 否 | 是否作用于满足条件的所有数据。默认:false |
LimitCount | 否 | 作用于满足条件的指定数据行数。当"IncludeAll=true"时有效。默认:1 |
Output | 否 | 数据影响行数输出到公共变量的变量名称。数据结构:{"AffectedRows":1} |
2.9 查询所有数据
- 组件程序集:LowcodeCore.ComponentParts.DataOperate.DataSelect
- JSON格式如下:
{
"Component": "LowcodeCore.ComponentParts.DataOperate.DataSelect",
"Parameters": {
"Entity": {
"ConnectionString": "Data Source=.\\SQL2019; Initial Catalog=Lowcode; Persist Security Info=True; User ID=sa; Password=123456;",
"Name": "Users",
"Type": "Table",
"SQL": ""
},
"Fields": [ "UserCode", "UserName" ],
"OrderBy": { "UserCode": "ASC" },
"Filter": "{ \"Sex\":0 }",
"Take": 0,
"Skip": 0,
"Output": "Users"
},
"Next": "End"
}
节点名称 | 是否必须 | 功能描述 |
---|---|---|
Entity.ConnectionString | 是 | 数据库连接字符串 |
Entity.Name | 是 | 表名 |
Entity.Type | 否 | 数据实体类型:Table,View,Procedure,Function,Custom(自定义) |
Entity.SQL | 否 | 自定义查询SQL。当该参数不为“空”时,以该SQL为数据查询实体(类似于视图) |
Fields | 否 | 指定查询数据列。缺省时查询所有字段 |
OrderBy | 否 | 指定排序字段和排序规则(升序:“ASC”或“1”,降序:“DESC”或“-1”)。 |
Filter | 否 | 过滤条件。支持“$.变量”取值。(详细语法见“Filter语法说明”) |
Take | 否 | 指定输出数据行数,默认:0。Take大于0时输出指定行数,否则输出满足条件的所有数据。 |
Skip | 否 | 指定跳过数据行数,默认:0。 |
Output | 否 | 数据影响行数输出到公共变量的变量名称。数据结构:[{"UserCode":"001","UserName":"张三"}] |
2.10 查询满足条件的第一条数据
- 组件程序集:LowcodeCore.ComponentParts.DataOperate.DataFirst
- JSON格式如下:
{
"Component": "LowcodeCore.ComponentParts.DataOperate.DataFirst",
"Parameters": {
"Entity": {
"ConnectionString": "Data Source=.\\SQL2019; Initial Catalog=Lowcode; Persist Security Info=True; User ID=sa; Password=123456;",
"Name": "Users",
"Type": "Table",
"SQL": ""
"Fields": [ "UserCode", "UserName" ],
"Filter": "{ \"Id\":\"$.HttpContext.Query.Id\" }",
"Output": "UsersFirst"
},
"Next": "End"
}
节点名称 | 是否必须 | 功能描述 |
---|---|---|
Entity.ConnectionString | 是 | 数据库连接字符串 |
Entity.Name | 是 | 表名 |
Entity.Type | 否 | 数据实体类型:Table,View,Procedure,Function,Custom(自定义) |
Entity.SQL | 否 | 自定义查询SQL。当该参数不为“空”时,以该SQL为数据查询实体(类似于视图) |
Fields | 否 | 指定查询数据列。缺省时查询所有字段 |
Filter | 否 | 过滤条件。支持“$.变量”取值。(详细语法见“Filter语法说明”) |
Output | 否 | 数据影响行数输出到公共变量的变量名称。数据结构:{"UserCode":"001","UserName":"张三"} |
2.11 数据记录总数统计
- 组件程序集:LowcodeCore.ComponentParts.DataOperate.DataCount
- JSON格式如下:
{
"Component": "LowcodeCore.ComponentParts.DataOperate.DataCount",
"Parameters": {
"Entity": {
"ConnectionString": "Data Source=.\\SQL2019; Initial Catalog=Lowcode; Persist Security Info=True; User ID=sa; Password=123456;",
"Name": "Users",
"Type": "Table",
"SQL": ""
},
"Filter": "{ \"Sex\":\"$.HttpContext.Query.Sex\" }",
"Output": "UsersDataCount"
},
"Next": "End"
}
节点名称 | 是否必须 | 功能描述 |
---|---|---|
Entity.ConnectionString | 是 | 数据库连接字符串 |
Entity.Name | 是 | 表名 |
Entity.Type | 否 | 数据实体类型:Table,View,Procedure,Function,Custom(自定义) |
Entity.SQL | 否 | 自定义查询SQL。当该参数不为“空”时,以该SQL为数据查询实体(类似于视图) |
Filter | 否 | 过滤条件。支持“$.变量”取值。(详细语法见“Filter语法说明”) |
Output | 否 | 数据影响行数输出到公共变量的变量名称。数据结构:{"Rows”:10} |
2.12 判断记录是否存在
- 组件程序集:LowcodeCore.ComponentParts.DataOperate.DataAny
- JSON格式如下:
{
"Component": "LowcodeCore.ComponentParts.DataOperate.DataAny",
"Parameters": {
"Entity": {
"ConnectionString": "Data Source=.\\SQL2019; Initial Catalog=Lowcode; Persist Security Info=True; User ID=sa; Password=123456;",
"Name": "Users",
"Type": "Table",
"SQL": ""
},
"Filter": "{ \"Sex\":\"$.HttpContext.Query.Sex\" }",
"Output": "UsersAny"
},
"Next": "End"
}
节点名称 | 是否必须 | 功能描述 |
---|---|---|
Entity.ConnectionString | 是 | 数据库连接字符串 |
Entity.Name | 是 | 表名 |
Entity.Type | 否 | 数据实体类型:Table,View,Procedure,Function,Custom(自定义) |
Entity.SQL | 否 | 自定义查询SQL。当该参数不为“空”时,以该SQL为数据查询实体(类似于视图) |
Filter | 否 | 过滤条件。支持“$.变量”取值。(详细语法见“Filter语法说明”) |
Output | 否 | 数据影响行数输出到公共变量的变量名称。数据结构:{"Any":True} |
2.13 分页查询
- 组件程序集:LowcodeCore.ComponentParts.DataOperate.TurnPageQuery
- JSON格式如下:
{
"Component": "LowcodeCore.ComponentParts.DataOperate.TurnPageQuery",
"Parameters": {
"Entity": {
"ConnectionString": "Data Source=.\\SQL2019; Initial Catalog=Lowcode; Persist Security Info=True; User ID=sa; Password=123456;",
"Name": "Users",
"Type": "",
"SQL": ""
},
"Fields": [ "UserCode", "UserName" ],
"OrderBy": { "UserCode": "ASC" },
"Filter": "{ \"Sex\":0 }",
"PageSize": "$.HttpContext.Query.PageSize",
"PageIndex": "$.HttpContext.Query.PageIndex",
"Output": "Users"
}
节点名称 | 是否必须 | 功能描述 |
---|---|---|
Entity.ConnectionString | 是 | 数据库连接字符串 |
Entity.Name | 是 | 表名 |
Entity.Type | 否 | 数据实体类型:Table,View,Procedure,Function,Custom(自定义) |
Entity.SQL | 否 | 自定义查询SQL。 当该参数“不为空”时,以该SQL为数据查询实体(类似于视图) |
Fields | 否 | 指定查询数据列。缺省时查询所有字段 |
OrderBy | 否 | 指定排序字段和排序规则(升序:“ASC”或“1”,降序:“DESC”或“-1”)。 |
Filter | 否 | 过滤条件,支持“$.变量”取值。(详细语法见“Filter语法说明”) |
PageSize | 否 | 每页数据行数。最小为:1。赋值小于1时,初始化为:10。支持“$.变量”取值 |
PageIndex | 否 | 第几页。最小为:1。赋值小于1时,初始化为:1。 支持“$.变量”取值 |
Output | 否 | 数据影响行数输出到公共变量的变量名称。 数据结构:{”PageIndex“:1,"PageSize":"10","TotalCount":180,"DataList":[{"UserCode":"001","UserName":"张三"},……]} |
2.14 存储过程执行
- 组件程序集:LowcodeCore.ComponentParts.DataOperate.ProcedureExecute
- JSON格式如下:
{
"Component": "LowcodeCore.ComponentParts.DataOperate.ProcedureExecute",
"Parameters": {
"Entity": {
"ConnectionString": "Data Source=.\\SQL2019; Initial Catalog=Lowcode; Persist Security Info=True; User ID=sa; Password=123456;",
"Name": "usp_UpdateUser",
"Type": "Procedure"
},
"Filter": "{ \"Id\":\"$.HttpContext.Query.Id\",\"UserName\":\"$.HttpContext.Form.UserName\"}",
"Output": "usp_UpdateUser"
},
"Next": "End"
}
节点名称 | 是否必须 | 功能描述 |
---|---|---|
Entity.ConnectionString | 是 | 数据库连接字符串 |
Entity.Name | 是 | 表名 |
Entity.Type | 否 | 数据实体类型:Table,View,Procedure,Function,Custom(自定义) |
Filter | 否 | 存储过程参数值。支持“$.变量”取值 |
Output | 否 | 数据影响行数输出到公共变量的变量名称。数据结构:{"AffectedRows":1} |
2.15 存储过程查询
- 组件程序集:LowcodeCore.ComponentParts.DataOperate.ProcedureQuery
- JSON格式如下:
{
"Component": "LowcodeCore.ComponentParts.DataOperate.ProcedureQuery",
"Parameters": {
"Entity": {
"ConnectionString": "Data Source=.\\SQL2019; Initial Catalog=Lowcode; Persist Security Info=True; User ID=sa; Password=123456;",
"Name": "usp_GetUser",
"Type": "Procedure"
},
"Filter": "{ \"Id\":\"$.HttpContext.Query.Id\" }",
"Output": "usp_GetUser"
}
"Next": "End"
}
节点名称 | 是否必须 | 功能描述 |
---|---|---|
Entity.ConnectionString | 是 | 数据库连接字符串 |
Entity.Name | 是 | 表名 |
Entity.Type | 否 | 数据实体类型:Table,View,Procedure,Function,Custom(自定义) |
Filter | 否 | 存储过程参数值。支持“$.变量”取值 |
Output | 否 | 数据影响行数输出到公共变量的变量名称。数据结构:[{"存储过程输出列":1,……}] |
3. 组件全局注册及使用
- 每个请求事务中的执行节点都需要指定组件的程序集路径。在实际操作开发运维过程中,可能需要对组件进行大版本升级,如果升级后的大版本采用了新的组件名称,那么之前基于组件开发事务JSON配置中的所有“Component”字段都需要进行调整,极为不便;以下为大家介绍如何实现“组件全局注册及使用方法”。
3.1 组件注册
- 在站点根目录下新建"Data"文件夹
- 在"Data"文件夹下新建JSON配置文件,如:"components.json"
- JSON格式如下:
{
"Components": {
"HttpContextStart": "LowcodeCore.ComponentParts.HttpContextStart",
"HttpContextEnd": "LowcodeCore.ComponentParts.HttpContextEnd",
"TurnPageQuery": "LowcodeCore.ComponentParts.DataOperate.TurnPageQuery",
"DataSelect": "LowcodeCore.ComponentParts.DataOperate.DataSelect",
"DataInsert": "LowcodeCore.ComponentParts.DataOperate.DataInsert",
"DataUpdate": "LowcodeCore.ComponentParts.DataOperate.DataUpdate",
"DataDelete": "LowcodeCore.ComponentParts.DataOperate.DataDelete",
"DataCount": "LowcodeCore.ComponentParts.DataOperate.DataCount",
"DataAny": "LowcodeCore.ComponentParts.DataOperate.DataAny",
"DataFirst": "LowcodeCore.ComponentParts.DataOperate.DataFirst",
"ProcedureExecute": "LowcodeCore.ComponentParts.DataOperate.ProcedureExecute",
"ProcedureQuery": "LowcodeCore.ComponentParts.DataOperate.ProcedureQuery"
}
}
注:JSON文件名称可自定义,但"Data"文件夹下根节点命名为"Components"的JSON文件中,该命名不支持自定义,不可以用于除组件注册外的其他场景。Components节点下注册的名称可以自定义,值对应组件程序集路径。
3.2 使用组件全局配置
- 例:配置翻页查询组件
- JSON格式如下:
{
"Component": "$.CommonSettings.Components.TurnPageQuery"
}
- "$."表示来源于全局变量
- "CommonSettings"固定写法。全局配置变量名(配置数据操作节点时,Output命名不可以与该名称出现重复,否则会覆盖该变量的值)
- "Components"固定写法。注册表根节点名称。
- "TurnPageQuery"组件注册表对于组件的别名。注册全局组件时可自定义,使用时配置一致即可
4. 数据库链接字符串全局配置及使用
- 通过组件执行数据操作,必须配置数据库链接字符串,但是对于中大型项目来说,每个操作都独立配置链接字符串对后期的数据库对象的调整运维来说极为不便。以下为大家介绍如何实现数据库链接字符串全局配置及使用方法。
4.1 注册数据库链接字符串
- 在站点根目录下新建"Data"文件夹
- 在"Data"文件夹下新建JSON配置文件,如:"database.json"
- JSON格式如下:
{
"Database": {
"Lowcode": "Data Source=.\\SQL2019; Initial Catalog=Lowcode; Persist Security Info=True; User ID=sa; Password=123456;"
}
}
注:JSON文件名称可自定义,但"Data"文件夹下根节点命名为"Database"的JSON文件中,该命名不支持自定义,不可以用于除数据库链接字符串的其他场景。Database节点下注册的名称可以自定义,值对应数据库链接字符串。
4.2 使用数据库链接字符串
- JSON格式如下:
{
"Component": "LowcodeCore.ComponentParts.DataOperate.TurnPageQuery",
"Parameters": {
"Entity": {
"ConnectionString": "$.CommonSettings.Database.Lowcode"
}
}
}
- "$."表示来源于全局变量
- "CommonSettings"固定写法。全局配置变量名(配置数据操作节点时,Output命名不可以与该名称重复,否则会覆盖该变量的值)
- "Database"固定写法。数据库全局配置根节点名称
- "Lowcode"数据库链接字符串别名。注册时可自定义,使用时配置一致即可
5. 请求安全及路由配置
5.1 路由配置
- 任何一个数据操作JSON管道配置后,需要配置API请求URL地址才可以触发执行。
- JSON格式如下:
{
"Routes": {
"/Lowcode/Demo": {
"Name": "LowcodeApi开始开发DEMO",
"JsonPath": "Data\\demo.json",
"Method": "GET",
"Accessibility": "Public",
"Roles": []
}
}
节点名称 | 描述 |
---|---|
Routes | 固定配置。路由配置文件根节点 |
/Lowcode/Demo | 自定义API请求URL相对路径 |
Name | 当前URL资源名称 |
JsonPath | 当前URL资源对于的执行事务JSON配置路径。支持相对路径、绝对路径 |
Method | 当前URL资源请求方法名,如:GET、POST等。不支持配置多个类型 |
Accessibility | 资源可访问性:Public,Protected,Private |
Roles | 资源授权访问角色,Accessibility=Private时有效 |
5.2 请求安全
每个URL请求对应的Routes配置中,Accessibility资源可访问性分为三个层次:
Accessibility | 特征 | 描述 |
---|---|---|
Public | 公共资源 | 无需授权,可任意访问 |
Protected | 受保护资源 | 用户完成身份校验后可访问。 判断逻辑:HttpContext.User.Identity.IsAuthenticated=true |
Private | 私有资源 | 用户完成身份校验且当前用户所属角色在可访问角色列表内可访问, 判断逻辑: HttpContext.User.Identity.IsAuthenticated=true 且 Roles.Any(role => HttpContext.User.IsInRole(role)。 注:Roles表示路由配置中的角色列表 |
注:用户鉴权与角色赋值过程,请使用.net6框架app.UseAuthorization()相关功能自行处理。
6. Filter语法说明
6.1 Filter操作符
- 通过组件执行数据查询过程中,需要进行数据过滤。Filter配置属于JSON对象转换为String后的值。支持多种操作表达式:
表达式 | 描述 | DEMO | SQL等价于 |
---|---|---|---|
$eq | 等于 | {"field":{"$eq":"val"}} 或 {"field":"val"} |
field = val |
$gt | 大于 | {"field":{"$gt":"val"}} | field > val |
$gte | 大于等于 | {"field":{"$gte":"val"}} | field >= val |
$lt | 小于 | {"field":{"$lt":"val"}} | field < val |
$lte | 小于等于 | {"field":{"$lte":"val"}} | field <=val |
$ne | 不等于 | {"field":{"$ne":"val"}} | field != val |
$like | 模糊匹配 | {"field":{"$like":"%val%"}} | field Like %val% |
$nlike | 非模糊匹配 | {"field":{"$nlike":"val"}} | field NOT Like %val% |
$in | 包含 | {"field":{"$in":[v1,v2,v3,…]}} | field IN(v1,v2,v3,…) |
$nin | 非包含 | {"field":{"$nin":[v1,v2,v3,…]}} | field NOT IN (v1,v2,v3,…) |
$or | 或 | {"$or":{n1:v1,n2:{"$eq":v2}},…} 或 {"$or":[{n1:v1,n2:v2,…},{n3:{"$eq":v3}},…]} |
((n1=v1) OR (n2=v2)) 或 ((n1=v1 AND n2=v2 AND...) OR (n3=v3) OR...) |
$and | 与 | {"$and":{n1:v1,…} 或 {"$and":[{n1:v1,n2:v2,…},{n3:{"$eq":v3}},…]} |
(n1=v1 AND ...) 或 ((n1=v1 and n2=v2 and ...) AND (n3=v3) AND ...) |
$not | 非 | {"$not":{n1:v1,n2:{"$eq":v2},…} | NOT (n1=v1 and n2=v2 and ...) |
$nor | 非或 | {"$nor":{n1:v1}…} 或 {"$nor":[{n1:v1,n2:v2,…},{n3:{"$eq":v3}},…]} |
NOT (n1=v1 OR n2=v2 OR ...) 或 NOT ((n1=v2 and n2=v2 and ...) OR (n3=v3) OR...) |
6.2 Filter操作符常用混合场景举例
- 过滤查询时,很多时候过滤条件比较复杂。以下枚举几类常用混合场景,以供参考:
SQL 场景 | Filter表达式 |
---|---|
k1=v1 and k2=v2 | {"k1":"v1",“k2”:{“$eq”:v2}} 或 {"$and":{"k1":"v1","k2":{"$eq":v2}}} 或 {"$and":[{"k1":"v1"},{"k2":{"$eq":v2}}]} |
k1=v1 or k2=v2 | {“$or”:{"k1":“v1”},“k2”:{“$eq”:v2}} 或 {"$or":[{“k1”:“v1”},{“k2”:{“$eq”:v2}}]} |
((k1=v1 and k2!=v2) or k3 not in(v3)) and (k4 like '%v4%') | {"$and":{"$or":{"k1":"v1","$ne":{"k2":v2}},{"k3":{"$nin":["v3"]}}},{"k4":"$like":"%v4%"}} |
7. 自定义组件及扩展
- LowcodeCore框架目前提供了最基本的数据操作功能,但是实际工作中可能还需要更多的复杂逻辑处理。所以框架提供了扩展支持。
7.1 Controller扩展
-
LowcodeCore框架基于.net管道处理请求,当URL地址在LowcodeCore路由中没有找到对应Path路径;或者存在对应的Path路径,但是Method不一致时,会重新回到原有.net管道。这也是为什么在文章LowcodeCore 低代码开发框架——快速搭建数据操作API、数据中台 3.1.3 章节中提到的“app.UseLowcode() 需要放在“app.MapControllers()”之前”的原因。
-
在项目Program.cs中注册“app.UseLowcode()”时,app.UseLowcode() 放在“app.MapControllers()”之前时,当Lowcode未匹配到URL请求资源时,会继续回到“app.MapControllers()”管道内,执行.net框架自带的Controller对象。
using LowcodeCore;
app.UseLowcode();
7.2 自定义组件
- LowcodeCore框架定义了基础的数据操作组件。也支持自定义组件。操作步骤如下:
7.2.1 步骤一:创建“类库”项目
- 创建一个目标框架为.net6 的类库项目,通过Nuget管理器安装“LowcodeCode”框架,或者直接引用以安装好的“LowcodeCore.dll”文件。
7.2.2 步骤二:创建“Provider.cs”文件
- 在项目中新建“ComponentProvider.cs”文件,并继承“LowcodeCore.ComponentIComponentProvider”接口。如:
注:接口中“categoryName”参数值对应 “3.1 组件注册”或“组件管道配置”中的“Component”配置值。
using LowcodeCore.Component;
namespace LowcodeCore.Componention
{
public class ComponentProvider : IComponentProvider
{
public IComponent? CreateComponent(string categoryName)
{
/*此处需根据“categoryName”值返回IComponent实例
if (categoryName == "LowcodeCore.Componention.HttpContextComponentV2.0")
{
return new HttpContextComponent();
}
*/
return null;
}
public void Dispose()
{
}
}
}
7.2.3 步骤三:定义“IComponent”组件实例
- 新建“自定名称Component.cs”文件,继承“LowcodeCore.Component.IComponent”接口。如:
using LowcodeCore.Component;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Configuration;
using System.Text.Json.Nodes;
namespace LowcodeCore.Componention
{
public class HttpContextComponent : IComponent
{
Task IComponent.Do(HttpContext context, IConfiguration configuration, IConfiguration parameters, JsonObject state)
{
//采集Query参数
var jsonObject = new JsonObject
{
["Query"] = JsonValue.Create(context.Request.Query),
};
//获取Output配置名称
var output = parameters.GetValue<string>("Output");
//将Query参数值写入到“state”全局变量
state[output] = jsonObject;
return Task.CompletedTask;
}
}
}
参数说明如下:
参数名 | 描述 |
---|---|
context | 当前请求HttpContext对象 |
configuration | 宿主站点appsettings.json配置信息 |
parameters | 当前组件使用时,在管道JSON配置中对应的“Parameters”配置节点 |
state | LowcodeCore请求管道中的全局缓存对象 。每个组件执行时都可以读取所有组件缓存的数据 |
7.2.4 步骤四:注册自定义组件"Provider"
- 在宿主站点下“Data”文件夹中新建“Provider”JSON注册文件,命名为:“componentproviders.json”
注:组件Provider相对路径“Data\componentproviders.json”为固定格式,不支持自定义。
- JSON配置文件如下:
{
"Libraries": {
"LowcodeCore.Componention/1.0.0": {
"path": "Data\\Components\\MyExtendProvider\\v1.0\\LowcodeCore.Componention.dll",
"categoryName": "LowcodeCore.Componention.ComponentProvider"
},
"LowcodeCore.Componention/2.0.0": {
"path": "Data\\Components\\MyExtendProvider\\v2.0\\LowcodeCore.Componention.dll",
"categoryName": "LowcodeCore.Componention.ComponentProvider"
}
}
}
参数名 | 描述 |
---|---|
Libraries | Provider程序集根节点。 固定语法。 |
LowcodeCore.Componention/1.0.0 | 自定义Provider名称/版本号(可自定义,不可重复) |
path | 步骤一、二、三中编译生成的DLL存放路径。支持“相对/绝对”路径 |
categoryName | 步骤二中定义的"Provider.cs"类程序集名称 |
注:
- 注册组件Provider之后,宿主站点重启后生效;
- 多个组件Provider项目dll相互隔离,命名空间名称可以重复,互不影响;
- 请求管道中按照“从下往上”的优先级,根据“categoryName”参数值从各个“Provider”中请求“IComponent”执行实例。如果从自定义Provider中成功获取到实例,不会再遍历后续Provider节点;如果从自定义Provider中未获取到实例,最后会在框架自带组件库中获取实例;
- 发布自定义组件Provider程序集时,如果存在外部引用DLL,需要同自定义组件Provider程序集dll文件放在相同文件夹下;
- 发布自定义组件Provider程序集时,不要包含LowcodeCore.dll文件;
7.2.5 步骤五:使用自定义组件
- 自定义组件用法与LowcodeCode框架自带组件使用方式一致;
- 可以直接将“自定义组件程序集名称”配置在“管道配置节点Component”中;
- 也可以参考“3.1 组件注册”注册到组件全局配置;
如:
{
"ID": "3D24CC45-AE39-43C2-8773-E14C99C903FC",
"Start": {
"Component": "LowcodeCore.ComponentParts.HttpContextStart",
"Parameters": {
"Output": "HttpContext"
},
"Next": "自定义组件使用DEMO_MyOutsiteComponentV2"
},
"自定义组件使用DEMO_MyOutsiteComponentV2": {
"Component": "LowcodeCore.Componention.HttpContextComponentV2.0",
"Parameters": {
"Output": "HttpContextV2"
},
"Next": "End"
},
"End": {
"Component": "LowcodeCore.ComponentParts.HttpContextEnd",
"Parameters": {
"Response": "$.HttpContext"
}
}
}
8. LowcodeCode框架扩展方法
8.1 JsonNode.GetNodeByPath
-
用途:按照指定path路径获取JsonNode对象
-
应用场景:自定义组件时,从"JsonObject state"参数中获取指定“path”对应的变量值(path格式:$.一级变量名.二级变量名);
-
使用DEMO:框架组件“LowcodeCore.ComponentParts.HttpContextEnd”中的“state.GetNodeByPath(path)”过程就是根据管道节点中配置的“Parameters.Response”参数值从“state”全局缓存中获取对应的JsonNode对象输出到页面
-
管道JSON配置:
{
"ID": "3D24CC45-AE39-43C2-8773-E14C99C903FC",
"Start": {
"Component": "LowcodeCore.ComponentParts.HttpContextStart",
"Parameters": {
"Output": "HttpContext"
},
"Next": "End"
},
"End": {
"Component": "LowcodeCore.ComponentParts.HttpContextEnd",
"Parameters": {
"Response": "$.HttpContext.Form.Files.fileupload"
}
}
}
- 框架组件“LowcodeCore.ComponentParts.HttpContextEnd”源码
using LowcodeCore.Component;
using LowcodeCore.Extensions;
using System.Text.Json.Nodes;
namespace LowcodeCore.ComponentParts
{
public class HttpContextEnd : IComponent
{
public Task Do(HttpContext context, IConfiguration configuration, IConfiguration Parameters, JsonObject state)
{
var path = Parameters.GetSection("Response").Get<string>();
context.Response.StatusCode = 200;
if (!string.IsNullOrWhiteSpace(path) && path.StartsWith("$."))
{
return context.Response.WriteAsJsonAsync(state.GetNodeByPath(path));
}
else if (!string.IsNullOrWhiteSpace(path))
{
return context.Response.WriteAsJsonAsync(path);
}
else
{
return context.Response.WriteAsJsonAsync(new JsonObject { ["success"] = true });
}
}
}
}
8.2 JsonNode.SetNodeByPath
-
用途:按照指定path路径设置JsonNode对象
-
应用场景:自定义组件时,将组件处理后的数据缓存到"JsonObject state"指定路径中;
-
使用DEMO:框架组件“LowcodeCore.ComponentParts.HttpContextStart”中的“state.SetNodeByPath(output, result)”过程就是根据管道节点中配置的“Parameters.Output”定义的参数名将JsonObject对象缓存到“state”对象中;
-
管道JSON配置:
{
"ID": "3D24CC45-AE39-43C2-8773-E14C99C903FC",
"Start": {
"Component": "LowcodeCore.ComponentParts.HttpContextStart",
"Parameters": {
"Output": "HttpContext"
},
"Next": "End"
},
"End": {
"Component": "LowcodeCore.ComponentParts.HttpContextEnd",
"Parameters": {
"Response": "$.HttpContext.Form.Files.fileupload"
}
}
}
- 框架组件“LowcodeCore.ComponentParts.HttpContextStart”源码
using LowcodeCore.Component;
using System.Text.Json.Nodes;
using System.Text.Json.Serialization;
using System.Text.Json;
using LowcodeCore.Extensions;
using Microsoft.EntityFrameworkCore.Metadata.Internal;
using Newtonsoft.Json.Linq;
namespace LowcodeCore.ComponentParts
{
public class HttpContextStart : IComponent
{
Task IComponent.Do(HttpContext context, IConfiguration configuration, IConfiguration Parameters, JsonObject state)
{
/*参数采集*/
var query = new JsonObject();
var forms = new JsonObject();
var headers = new JsonObject();
var cookies = new JsonObject();
var jsonbody = new JsonObject();
/*详细处理过程省略*/
var result = new JsonObject
{
["Query"] = query,
["Form"] = forms,
["Headers"] = headers,
["Cookies"] = cookies,
["FromBody"] = jsonbody
};
var output = Parameters.GetValue<string>("Output");
if (!string.IsNullOrWhiteSpace(output))
{
state.SetNodeByPath(output, result);
}
return Task.FromResult(result);
}
8.3 JsonNode.VariableBuild
-
用途:将Json字符串中的"$.变量名"配置值,替换成指定JsonNode对象对应“Path”下的实际值;
-
应用场景:定义组件时,部分参数值需要取值与“state”中的JsonNode对象;
-
使用DEMO:框架组件“LowcodeCore.ComponentParts.DataOperate.DataSelect”数据查询,“state.VariableBuild(option.Filter)”过程就是将“Parameters.Filter”对应的“JSON字符串”中的“$.HttpContext.Query.Sex”路径转换为“state”缓存中对应Path下的实际值;
-
管道JSON配置:
{
"ID": "C6765C2E-E1A2-4C4C-9ED7-44ECFA0D839E",
"Start": {
"Component": "LowcodeCore.ComponentParts.HttpContextStart",
"Parameters": {
"Output": "HttpContext"
},
"Next": "DataSelect"
},
"DataSelect": {
"Component": "LowcodeCore.ComponentParts.DataOperate.DataSelect",
"Parameters": {
"Entity": {
"ConnectionString": "Data Source=.\\SQL2019; Initial Catalog=Lowcode; Persist Security Info=True; User ID=sa; Password=123456;",
"Name": "Users",
"Type": "Table",
"SQL": ""
},
"Fields": [ "UserCode", "UserName" ],
"OrderBy": { "UserCode": "ASC" },
"Filter": "{ \"Sex\":\"$.HttpContext.Query.Sex\" }",
"Take": 5,
"Skip": 0,
"Output": "Users"
},
"Next": "End"
},
"End": {
"Component": "LowcodeCore.ComponentParts.HttpContextEnd",
"Parameters": {
"Response": "$.Users"
}
}
}
- 框架组件“LowcodeCore.ComponentParts.DataOperate.DataSelect”源码
using LowcodeCore.Component;
using LowcodeCore.Extensions;
using LowcodeCore.MSSQL;
using System.Text.Json;
using System.Text.Json.Nodes;
namespace LowcodeCore.ComponentParts.DataOperate
{
public class DataSelect : IComponent
{
public Task Do(HttpContext context, IConfiguration configuration, IConfiguration Parameters, JsonObject state)
{
var option = Parameters.Get<DataSelectOption>();
//参数替换
option.Filter = state.VariableBuild(option.Filter);
/*其他过程省略*/
return Task.FromResult(result);
}
}
}