Files
MesUniversalApi-Migration/working/MESCommonBase响应输出与SqlWebCall默认分支详细文档.md

940 lines
23 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# MESCommonBase 响应输出与 SqlWebCall 默认分支详细文档
文档范围:流程图中下半部分的两块内容。
- `响应输出`
- `DataLink.SqlWebCall 默认分支`
关联入口:`MES_Manage/submit/MESCommonBase.ashx`
生成时间2026-07-02
## 1. 相关程序清单
| 程序文件 | 关键位置 | 作用 |
| --- | --- | --- |
| `MES_Manage/submit/MESCommonBase.ashx` | `ProcessRequest``switch(type)` 和外层 `catch` | 负责把不同 Type 的结果写入 HTTP 响应 |
| `02DataLinkMesWork/DataLinkMesWork.SqlWebCall.cs` | `DataLink.SqlWebCall(int type, JsonData jsonData, jsonobj dataobj)` | 默认分支二次分发入口 |
| `02DataLinkMesWork/DataLinkMesWork.SqlWebCall.cs` | `InitSystemReg(...)` | 初始化数据库连接字符串 |
| `02DataLinkMesWork/DataLinkMesWork.SqlWebCall.cs` | `GetString_JsonData(...)` | 从新协议 JSON 读取 `Type/Name/Param/token` 等字段 |
| `02DataLinkMesWork/DataLinkMesWork.cs` | `ExePROCEDURE_Type*``ExecuteInsertMesWork``ExecuteSelectMesWork` | 具体 SQL、存储过程、登录、分页、返回格式处理 |
| `02DataLinkMesWork/P0.MES.Common/bizDataAccess/SQLCommon.cs` | `ExecuteStoredProcedure``ExecuteDataTable``ExecuteDataset``ExecuteInsertMesWork``ExecuteSelectMesWork` | 底层 ADO.NET 数据库执行封装 |
| `01BasicData/BasicData/BasicData.cs` | `jsonobj` | 旧协议请求对象 |
| `MES_Manage/Web.config` | `appSettings["ConnectionString"]` | 默认数据库连接配置来源 |
## 2. 这部分在总流程中的位置
`MESCommonBase.ashx` 先解析请求体或 `param` 参数,拿到 `type` 后进入 `switch(type)`
流程图下半部分对应的是:
```text
switch(type)
|
|-- 文件下载分支 2001/2002/2003/2004/16 -> 响应输出:二进制下载
|-- 文件上传分支 15 -> 响应输出JSON 文本
|-- IP 查询分支 4000 -> 响应输出:文本 IP
|-- default -> DataLink.SqlWebCall(...) -> 响应输出JSON 文本
```
也就是说,`响应输出` 是所有分支最终面向 HTTP 客户端的出口;`DataLink.SqlWebCall 默认分支` 是普通业务请求的二次路由器。
## 3. 响应输出:程序流程
### 3.1 默认响应头
`ProcessRequest` 进入后先执行:
```csharp
context.Response.ContentType = "application/json";
```
因此除文件下载分支外,默认都会以 `application/json` 作为响应类型。需要注意:`Type=4000` 实际写出的是纯文本 IP但 Content-Type 没有改成 `text/plain`
### 3.2 二进制下载响应
适用 Type
- `2001`
- `2002`
- `2003`
- `2004`
- `16`
典型代码模式:
```csharp
HttpContext.Current.Response.ContentType = "application/octet-stream";
HttpContext.Current.Response.AddHeader(
"Content-Disposition",
"attachment; filename=" + HttpUtility.UrlEncode(fileName, Encoding.UTF8)
);
HttpContext.Current.Response.AddHeader(
"Access-Control-Expose-Headers",
"Content-Disposition"
);
HttpContext.Current.Response.BinaryWrite(bytes);
HttpContext.Current.Response.Flush();
HttpContext.Current.Response.End();
```
字段含义:
| 字段 | 含义 |
| --- | --- |
| `ContentType = application/octet-stream` | 告诉浏览器按二进制文件处理 |
| `Content-Disposition = attachment` | 触发浏览器下载,而不是直接打开 |
| `filename=...` | 下载文件名,使用 UTF-8 URL 编码处理中文文件名 |
| `Access-Control-Expose-Headers` | 允许跨域前端读取 `Content-Disposition` 响应头 |
| `BinaryWrite(bytes)` | 写出文件二进制 |
| `Flush()` | 刷新响应缓冲区 |
| `End()` / `Close()` | 结束响应 |
不同文件分支的差异:
| Type | 生成文件的程序 | 文件名来源 | 结束方式 |
| --- | --- | --- | --- |
| `2001` | `ExcelWebCall.ExcelFile(...)` | `fileName + "." + fileExtension` | `Response.End()` |
| `2002` | `ExcelWebCall.ExcelFilePdf(...)` | `fileName + "." + fileExtension`,通常为 PDF | `Response.End()` |
| `2003` | `ExcelWebCall.ExcelFile(...)` | `fileName + "." + dataimg[0]` | `Response.Close()` |
| `2004` | `DataLink.ExePROCEDURE_Type2004(...)` | 数据库返回文件名和扩展名 | `Response.End()` |
| `16` | `DataLink.ExePROCEDURE_Type16(...)` | 数据库返回文件名和后缀 | `Response.End()` |
### 3.3 Type=16 的空文件处理
`Type=16` 下载前有一层空判断:
```csharp
DataLink.ExePROCEDURE_Type16(jsonData, out bytes, out fileName, out suffix);
if (bytes == null) return;
```
如果下游没有返回文件二进制,则直接 `return`,不会写 JSON 错误,也不会写文件响应。调用方看到的可能是空响应。
### 3.4 Type=15 上传文件后的 JSON 响应
`Type=15` 是上传文件分支,不返回下载流。
流程:
```text
读取 context.Request.Files
|
|-- 有文件:
| 读取第一个文件 InputStream 为 byte[]
| 从 FileName 拆 name/suffix
| 调 DataLink.ExePROCEDURE_Type15(jsonData, name, suffix, bytes)
| Response.Write(responseText)
|
|-- 无文件:
name=""
suffix=""
bytes=new byte[1]
调同一个 ExePROCEDURE_Type15
Response.Write(responseText)
```
`responseText` 来自下游存储过程调用,常见返回:
```json
[{"result":"1"}]
```
或:
```json
[{"result":"0"}]
```
### 3.5 Type=4000 的文本响应
`Type=4000` 返回请求 IP
```csharp
context.Response.Write(userIP);
```
当前 IP 判断逻辑:
```csharp
if (context.Request.ServerVariables["HTTP_X_FORWARDED_FOR"] != "")
userIP = context.Request.ServerVariables["REMOTE_ADDR"];
else
userIP = context.Request.ServerVariables["HTTP_X_FORWARDED_FOR"];
if (userIP == null || userIP == "")
userIP = context.Request.UserHostAddress;
```
注意:这里逻辑疑似写反。通常 `HTTP_X_FORWARDED_FOR` 有值时才优先取它;当前代码在有转发头时反而取 `REMOTE_ADDR`
### 3.6 default 分支的 JSON 响应
普通业务请求进入 default
```csharp
responseText = DataLinkMesWork.DataLink.SqlWebCall(type, jsonData, dataobj);
context.Response.Headers.Remove("Server");
context.Response.Write(responseText);
```
特点:
- 响应体完全由 `SqlWebCall` 返回值决定。
- 尝试移除 `Server` 响应头。
- 仍使用入口处默认的 `application/json`
- `SqlWebCall` 对未支持 Type 返回空字符串。
### 3.7 外层异常响应
`ProcessRequest` 外层包了一个总 `try/catch`
```csharp
string responseText = "NULL";
try
{
...
}
catch(Exception err)
{
context.Response.Write(responseText);
}
```
异常后的响应行为:
- 不记录异常。
- 不设置 HTTP 状态码。
- 写出当前 `responseText`
- 如果异常发生在下游调用前,返回 `"NULL"`
- 如果异常发生在 `responseText` 已赋值之后,可能返回旧结果。
## 4. DataLink.SqlWebCall 默认分支:入口流程
入口签名:
```csharp
public static string SqlWebCall(int type, JsonData jsonData, jsonobj dataobj)
```
调用来源:
```csharp
DataLinkMesWork.DataLink.SqlWebCall(type, jsonData, dataobj)
```
调用时机:`MESCommonBase.ashx``switch(type)` 没有匹配到 `2001/2002/2003/2004/15/16/4000` 时进入。
### 4.1 初始化数据库连接
`SqlWebCall` 开始时检查静态字段 `initSystemIsOk`
```csharp
if (!initSystemIsOk)
{
if (!InitSystemReg(out resultReg))
{
return resultReg;
}
}
```
`InitSystemReg` 当前实际逻辑:
```csharp
connectionString = ConfigurationManager.AppSettings["ConnectionString"];
initSystemIsOk = true;
return true;
```
说明:
- 第一次进入 `SqlWebCall` 时,从 `Web.config` 读取 `ConnectionString`
- 成功后设置静态标记,后续调用复用。
- 原先注册号、序列号、加密连接串等校验逻辑已经被注释。
### 4.2 二次分发
初始化后进入 `switch(type)`
```text
SqlWebCall(type,jsonData,dataobj)
|
|-- 8888 / 5001 / 5002加密、注册/改密、登录
|-- 1 / 2 / 5旧协议存储过程
|-- 11 / 111 / 12 / 13 / 21新协议存储过程
|-- 1001 / 1002 / 3 / 4 / 7 / 22 / 3001SQL、建表导入、SQL 命令
```
`SqlWebCall` 自身不直接访问数据库;它只选择具体方法。真正数据库执行在:
- `DataLinkMesWork.cs`
- `SQLCommon.cs`
## 5. SqlWebCall 支持的 Type 明细
### 5.1 登录、注册、加密类
| Type | 方法 | 输入对象 | 主要流程 | 返回 |
| --- | --- | --- | --- | --- |
| `8888` | `GetEncryptStr(jsonData)` | 新协议 `JsonData` | 读取 `Name/name`,用 `AesKeyIvGenerator.Encrypt(name1, SN, SN)` 加密 | 加密字符串,失败默认 `[]` |
| `5001` | `ExePROCEDURE_Type11_AddUser(jsonData)` | 新协议 `JsonData` | 读取 `Param` 数组,找到 `Password` 后 MD5再执行 `Name` 指定存储过程 | 存储过程首表 JSON 或 `[]` |
| `5002` | `ExePROCEDURE_Type11_Login(jsonData)` | 新协议 `JsonData` | 解密前端密码,执行 `Name` 指定存储过程查账号,再比对数据库密码,成功后写入 token | 成功返回用户表 JSON 并追加 `token`,失败返回 `result=0,msg=...` |
登录成功后会调用固定存储过程:
```text
权限管理_Token_增加数据
```
校验 token 时调用:
```text
权限管理_Token_查询数据
```
### 5.2 旧协议存储过程类
旧协议使用 `BasicData.jsonobj dataobj`,字段为:
```csharp
public string Type;
public string ModularID;
public string Name;
public string Param;
public string UserID;
public string Pagination;
public string token;
public bool HasReturn;
```
| Type | 方法 | 执行对象 | 参数格式 | 返回 |
| --- | --- | --- | --- | --- |
| `1` | `ExePROCEDURE_Type1(dataobj)` | `Name` 的第一个 `&` 前作为存储过程名 | `@p=value=type&@p2=value=type` | 首个 DataTable JSON分页时返回带总数结构失败 `result=0` |
| `2` | `ExePROCEDURE_Type2(dataobj)` | `Name` 指定存储过程 | 同 Type 1 | 成功 `result=1`,失败 `result=0` |
| `5` | `ExePROCEDURE_Type5(dataobj)` | `Name` 指定存储过程 | `@p&value&type|@p2&value&type` | 首个 DataTable JSON参数错误返回中文错误字符串 |
旧协议参数解析在 `SQLCommon.GetCmdParam(...)` 中完成:
```text
多个参数:用 & 分隔
单个参数:参数名=值=类型
输出参数:参数名=值=类型=output
```
支持类型:
- `int`
- `string`
- `boolean`
- `datetime`
- 默认按字符串处理
token 行为:
- `Type=1/2/3/4/5` 都是“如果 token 非空则校验”。
- 不传 token 时通常不会拒绝执行。
### 5.3 新协议存储过程类
新协议使用 `JsonData jsonData`,字段从请求 JSON 中读取:
```json
{
"type": "11",
"name": "存储过程名",
"param": "[{\"name\":\"@p\",\"value\":\"v\",\"type\":\"string\"}]",
"token": "..."
}
```
通用字段读取由 `GetString_JsonData(...)` 完成,兼容大小写:
| 大写字段 | 小写字段 | 含义 |
| --- | --- | --- |
| `Type` | `type` | Type |
| `Name` | `name` | 存储过程名或 SQL 文本 |
| `Param` | `param` | 参数数组字符串 |
| `UserID` | `userID` | 用户 |
| `Pagination` | `pagination` | 旧分页参数 |
| `HasReturn` | `hasReturn` | 是否返回 |
| `ModularID` | `modularID` | 模块 |
| `token` | `token` | token |
#### Type=11查询型存储过程
方法:
```csharp
ExePROCEDURE_Type11(jsonData)
```
流程:
```text
读取 Name/Param/token
|
|-- token 非空CheckToken(token),失败返回 [{"result":"3"}]
|
|-- Param 为空:无参数执行存储过程
|-- Param 非空:解析 JSON 数组为 SqlParameter[]
|
|-- SQLCommon.ExecuteStoredProcedure(... out DataSet ...)
|
|-- 有结果表:
|-- 有 pageSize/pageList内存分页返回分页 JSON
|-- 无分页字段:返回首个 DataTable JSON
|
|-- 有 output 参数:包装为 {"result":..., "output":...}
```
#### Type=111服务端分页存储过程
方法:
```csharp
ExePROCEDURE_Type111(jsonData)
```
它解决“通讯服务器分页”的问题。
如果请求中包含:
```json
{
"pageSize": 20,
"pageList": 1
}
```
程序会自动向参数数组追加 4 个参数:
| 参数名 | 值 | 说明 |
| --- | --- | --- |
| `PageCurrent` | `pageList` | 当前页 |
| `PageSize` | `pageSize` | 每页条数 |
| `PageCount` | `1111``type=int``output=1` | 输出参数 |
| `ItemCount` | `1111``type=int``output=1` | 输出参数,总记录数 |
执行后返回:
```json
{
"rows": [],
"total": "总记录数"
}
```
其中 `total` 来自输出参数 `ItemCount`
#### Type=12执行型存储过程
方法:
```csharp
ExePROCEDURE_Type12(jsonData)
```
特点:
- 执行 `Name/name` 指定存储过程。
- 不关注 DataSet。
- 成功返回:
```json
[{"result":"1"}]
```
- 失败返回:
```json
[{"result":"0"}]
```
- 如果有输出参数,返回:
```json
{
"result": [{"result":"1"}],
"output": [{"参数名":"参数值"}]
}
```
#### Type=13返回 DataSet JSON
方法:
```csharp
ExePROCEDURE_Type13(jsonData)
```
特点:
- 执行 `Name/name` 指定存储过程。
- 返回整个 `DataSet` 的 JSON而不是只返回第一张表。
- 有输出参数时包装为:
```json
{
"result": { "DataSet序列化结果": "..." },
"output": [{"参数名":"参数值"}]
}
```
#### Type=21新响应结构的存储过程
方法:
```csharp
ExePROCEDURE_Type21(jsonData)
```
特点:
- 仍然执行 `Name/name` 指定存储过程。
- 返回结构改为:
```json
{
"code": "200",
"message": "",
"data": {}
}
```
或:
```json
{
"code": "500",
"message": "错误信息",
"data": {}
}
```
注意:这里是否成功主要看底层返回的 `result` 字符串是否为空,不完全等同于数据库是否返回数据。
### 5.4 SQL 文本和建表导入类
| Type | 方法 | 执行对象 | 返回 |
| --- | --- | --- | --- |
| `1001` | `ExecuteInsertMesWork(jsonData)` | `Name/name` 作为 SQL 文本,参数来自 `Param` JSON 数组 | 成功 `result=1`;有输出时返回 `output` |
| `1002` | `ExecuteSelectMesWork(jsonData)` | `Name/name` 作为 SQL 查询文本,参数来自 `Param` JSON 数组 | DataTable JSON支持 `pageSize/pageList` 内存分页 |
| `3` | `ExePROCEDURE_Type3(dataobj)` | `dataobj.Name` 作为 SQL 查询文本 | DataTable JSON |
| `4` | `ExePROCEDURE_Type4(dataobj)` | `dataobj.Name` 作为非查询 SQL 文本 | 成功 `result=1` |
| `7` | `ExePROCEDURE_Type7(jsonData)` | `Name/name` 作为表名,`Param` 作为行数据 | 删除并重建表,批量插入,成功 `result=1` |
| `22` | `ExePROCEDURE_Type22(dataobj)` | `dataobj.Name` 作为 SQL 文本 | `{ code, message, data }` |
| `3001` | `DbCallType1003_SqlCmd.SqlExec(jsonData)` | SQL 命令执行入口 | 由该方法决定 |
这类 Type 的共性:
- 执行对象来自客户端 `Name/name`
- 参数虽然使用 `SqlParameter` 绑定,但 SQL 文本或表名本身不是固定白名单。
- 需要调用方和网络边界可信,否则风险很高。
## 6. SqlWebCall 参数处理流程
### 6.1 新协议 Param 数组字符串
常见格式:
```json
{
"type": "11",
"name": "存储过程名",
"param": "[{\"name\":\"@工位号\",\"value\":\"OP10\",\"type\":\"string\"},{\"name\":\"@数量\",\"value\":\"10\",\"type\":\"int\"}]"
}
```
处理逻辑:
```text
param 字符串
|
|-- JsonMapper.ToObject(param)
|
|-- 遍历数组
|-- nameSqlParameter 名
|-- value参数值如果是数组转为逗号字符串并做 Unicode 解码
|-- type存在时做类型转换
|-- output == "1":改为输出参数
|
|-- SQLCommon.ExecuteStoredProcedure / ExecuteSelectMesWork / ExecuteInsertMesWork
```
支持类型主要为:
- `int`
- `string`
- `boolean`
- `bool`
- `datetime`
- 默认字符串
### 6.2 旧协议 Param 拼接字符串
Type 1/2 的旧协议格式:
```text
@p1=value1=string&@p2=10=int&@out=0=int=output
```
`SQLCommon.GetCmdParam(...)` 处理逻辑:
```text
Param
|
|-- 按 & 分割参数
|-- 过滤包含 == / null / undefined 的项
|-- 每项按 = 分割
|-- 长度 2直接字符串参数
|-- 长度 3按类型转换
|-- 长度 4 且第 4 项为 output设为输出参数
```
Type 5 的旧协议格式不同:
```text
@p1&value1&String|@p2&10&Int
```
## 7. 底层数据库执行链路
### 7.1 存储过程查询
典型调用链:
```text
MESCommonBase.ashx default
-> DataLink.SqlWebCall(...)
-> DataLink.ExePROCEDURE_Type11/13/21(...)
-> SQLCommon.ExecuteStoredProcedure(...)
-> SqlConnection / SqlDataAdapter
-> DataSet / DataTable
-> JsonHelper / JsonConvert 序列化
-> Response.Write(responseText)
```
`SQLCommon.ExecuteStoredProcedure(... out DataSet ...)` 的关键行为:
- 创建 `SqlConnection`
- 创建 `SqlCommand(procedureName, conn)`
- 设置 `CommandType = StoredProcedure`
- 设置 `CommandTimeout = 0`,即不限制命令超时。
- 添加 `SqlParameter[]`
- 使用 `SqlDataAdapter.Fill(ds)` 填充结果集。
- 异常时写 `ApplicationLog`,并通过 `errorMessage` 返回异常字符串。
### 7.2 SQL 查询
典型调用链:
```text
Type 1002 / 3 / 22
-> SQLCommon.ExecuteSelectMesWork 或 ExecuteDataTable / ExecuteDataset
-> SqlDataAdapter(sql, conn)
-> Fill(DataTable/DataSet)
-> JSON
```
### 7.3 SQL 增删改
典型调用链:
```text
Type 1001 / 4
-> SQLCommon.ExecuteInsertMesWork 或 ExecuteNonQuery
-> SqlCommand.CommandText = SQL 文本
-> ExecuteNonQuery / ExecuteScalar
-> result=1 或 result=0
```
## 8. 返回格式汇总
### 8.1 成功返回首表 JSON
常见于:
- `Type=1`
- `Type=3`
- `Type=5`
- `Type=11`
- `Type=1002`
示例:
```json
[
{
"字段1": "值1",
"字段2": "值2"
}
]
```
### 8.2 成功/失败标志
常见于:
- `Type=2`
- `Type=4`
- `Type=12`
- `Type=1001`
成功:
```json
[{"result":"1"}]
```
失败:
```json
[{"result":"0"}]
```
### 8.3 token 失败
部分方法在 token 非空且校验失败时返回:
```json
[{"result":"3"}]
```
### 8.4 输出参数包装
普通输出参数:
```json
{
"result": [{"result":"1"}],
"output": [{"@out":"123"}]
}
```
分页输出参数:
```json
{
"rows": [],
"total": "123"
}
```
### 8.5 新结构响应
常见于:
- `Type=21`
- `Type=22`
```json
{
"code": "200",
"message": "",
"data": {}
}
```
失败:
```json
{
"code": "500",
"message": "错误信息",
"data": {}
}
```
### 8.6 空或未支持 Type
`SqlWebCall` 对未匹配 Type 没有 default 处理,`result` 初始为空字符串。
因此 `MESCommonBase.ashx` default 分支可能返回空响应体:
```text
""
```
如果进入外层异常,则可能返回:
```text
NULL
```
## 9. 鉴权与 token 逻辑
`CheckToken(token)` 逻辑:
```text
token == "" -> true
token 非空:
调 权限管理_Token_查询数据
|
|-- 存储过程报错 -> false
|-- 返回空表 -> false
|-- 返回有数据 -> true
```
关键影响:
- 多数业务方法只有在 `token` 非空时才调用 `CheckToken`
- 如果请求不传 token常见路径不会拒绝。
- `SqlWebCall` 入口层没有统一鉴权。
- 因此权限控制依赖调用方是否传 token以及下游存储过程是否自行校验。
## 10. 风险点与维护注意事项
### 10.1 响应层风险
1. `Response.End()` 位于大 try 内,可能触发 `ThreadAbortException`,随后外层 catch 写出 `responseText`
2. 下载失败时没有统一 JSON 错误,`Type=16``bytes == null` 会直接空返回。
3. `Type=4000` 返回纯文本,但 Content-Type 仍可能是 `application/json`
4. 外层异常不记录日志,定位问题困难。
5. 多种响应格式混用,前端必须按 Type 分别处理。
### 10.2 SqlWebCall 风险
1. 客户端可通过 `Name/name` 指定存储过程名、SQL 文本或表名。
2. `Type=3/4/22/1001/1002/3001` 存在直接 SQL 执行能力。
3. `Type=7` 可根据请求表名执行 `DROP TABLE``CREATE TABLE`
4. token 校验不是统一强制的。
5. `CommandTimeout = 0` 可能导致长时间阻塞。
6. 失败返回经常只有 `result=0`,缺少错误原因。
### 10.3 参数层风险
1. 新协议 `Param` 是 JSON 字符串,不是 JSON 对象;调用方需要二次转义。
2. 输出参数类型转换依赖 `type``output` 字段,格式错误会进入 catch 并返回 `result=0`
3. 数组参数被拼成逗号字符串,数组元素里如果本身包含逗号,语义会丢失。
4. 旧协议分隔符为 `&``=``|`,参数值包含这些字符时容易解析错误。
## 11. 建议改进方案
### 11.1 低成本修复
-`MESCommonBase.ashx` default 分支前统一校验 token。
- 未支持 Type 返回明确错误:
```json
{"code":"400","message":"Unsupported Type","data":null}
```
- 下载分支改为 `HttpContext.Current.ApplicationInstance.CompleteRequest()`,避免 `Response.End()` 的线程中止异常。
- `Type=4000` 设置 `ContentType = "text/plain"`,并修正代理 IP 判断逻辑。
- 外层 catch 记录异常Type、Name、IP、异常堆栈。
### 11.2 中期改造
- 建立 `Type + Name` 白名单,禁止任意存储过程名和 SQL 文本。
-`Param` 从“JSON 字符串”改为真正的 JSON 数组字段。
- 统一 JSON 返回结构:
```json
{
"code": "200",
"message": "",
"data": {}
}
```
- 将 SQL 执行类 Type 与普通业务接口分离。
### 11.3 长期改造
- 按业务模块拆分接口,减少万能网关。
- 数据库账号按能力拆分权限。
- 移除明文连接字符串,使用部署环境密钥。
- 对文件下载、上传、SQL 执行加入审计日志和限流。
## 12. 典型流程示例
### 12.1 Type=11 查询型存储过程
请求:
```json
{
"type": "11",
"name": "MES_工位_查询",
"param": "[{\"name\":\"@工位号\",\"value\":\"OP10\",\"type\":\"string\"}]",
"token": "token值"
}
```
流程:
```text
MESCommonBase.ashx default
-> SqlWebCall(11,jsonData,dataobj)
-> InitSystemReg 读取连接字符串
-> ExePROCEDURE_Type11
-> GetString_JsonData 读取 name/param/token
-> token 非空则 CheckToken
-> Param 转 SqlParameter[]
-> SQLCommon.ExecuteStoredProcedure
-> JsonHelper.DataTableToJson
-> Response.Write(JSON)
```
### 12.2 Type=111 分页型存储过程
请求:
```json
{
"type": "111",
"name": "MES_工位_分页查询",
"param": "[{\"name\":\"@关键字\",\"value\":\"OP\",\"type\":\"string\"}]",
"pageSize": 20,
"pageList": 1
}
```
内部自动追加分页参数:
```text
PageCurrent = 1
PageSize = 20
PageCount = 输出参数
ItemCount = 输出参数
```
响应:
```json
{
"rows": [],
"total": "100"
}
```
### 12.3 Type=1002 SQL 查询
请求:
```json
{
"type": "1002",
"name": "select * from Test where f1=@f1",
"param": "[{\"name\":\"@f1\",\"value\":\"T002\",\"type\":\"string\"}]"
}
```
流程:
```text
SqlWebCall(1002)
-> ExecuteSelectMesWork(jsonData)
-> SQLCommon.ExecuteSelectMesWork(sql, params, connectionString, out dt)
-> DataTableToJson
```
说明:参数值通过 `SqlParameter` 绑定,但 SQL 文本本身来自请求。
## 13. 结论
流程图中的 `响应输出` 是整个 `MESCommonBase.ashx` 的 HTTP 出口负责二进制下载、JSON 文本、IP 文本和异常兜底输出。`DataLink.SqlWebCall 默认分支` 是普通业务请求的二次分发中心,它按 Type 调用不同数据库执行方法覆盖登录、存储过程、SQL 查询、SQL 增删改、分页和新结构返回。
这部分程序的核心问题不是流程复杂,而是执行权过于通用:客户端可通过 `type + name + param` 控制大量数据库行为。维护时应优先关注统一鉴权、Type/Name 白名单、异常日志和响应格式统一。