🐛fix: 动态API参数大小写的问题

This commit is contained in:
yubaolee
2025-11-30 21:22:10 +08:00
parent 7cd738e7a7
commit fb7c1392a1
2 changed files with 722 additions and 73 deletions

View File

@@ -8,6 +8,7 @@ using OpenAuth.App.Response;
using SqlSugar;
using OpenAuth.App.Request;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
namespace OpenAuth.App
{
@@ -31,6 +32,59 @@ namespace OpenAuth.App
this.logger = logger;
}
#region -
/// <summary>
/// 将普通字典转换为大小写不敏感的字典
/// </summary>
private Dictionary<string, object> ToIgnoreCaseDict(Dictionary<string, object> source)
{
var result = new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase);
if (source != null)
{
foreach (var kvp in source)
{
result[kvp.Key] = kvp.Value;
}
}
return result;
}
/// <summary>
/// 检查字典中是否包含指定键(大小写不敏感)
/// </summary>
private bool ContainsKeyIgnoreCase(Dictionary<string, object> dict, string key)
{
return dict.Keys.Any(k => string.Equals(k, key, StringComparison.OrdinalIgnoreCase));
}
/// <summary>
/// 获取字典中指定键的值(大小写不敏感)
/// </summary>
private object GetValueIgnoreCase(Dictionary<string, object> dict, string key)
{
var kvp = dict.FirstOrDefault(x => string.Equals(x.Key, key, StringComparison.OrdinalIgnoreCase));
return kvp.Value;
}
/// <summary>
/// 设置字典中指定键的值(保留原始键名,大小写不敏感查找)
/// </summary>
private void SetValueIgnoreCase(Dictionary<string, object> dict, string key, object value)
{
var existingKey = dict.Keys.FirstOrDefault(k => string.Equals(k, key, StringComparison.OrdinalIgnoreCase));
if (existingKey != null)
{
dict[existingKey] = value;
}
else
{
dict[key] = value;
}
}
#endregion
/// <summary>
/// 获取表数据列表
/// </summary>
@@ -154,37 +208,42 @@ namespace OpenAuth.App
return result;
}
// 将对象转换为字典
var dict = JsonHelper.Instance.Deserialize<Dictionary<string, Object>>(req.Obj);
// 将对象转换为字典(使用大小写不敏感的反序列化)
var rawDict = JsonConvert.DeserializeObject<Dictionary<string, object>>(req.Obj);
var dict = ToIgnoreCaseDict(rawDict);
// 设置ID
if (!dict.ContainsKey("Id"))
{
dict["Id"] = Guid.NewGuid().ToString();
}
else if (string.IsNullOrEmpty(dict["Id"]?.ToString()))
// 设置ID(大小写不敏感检查)
if (!ContainsKeyIgnoreCase(dict, "Id"))
{
dict["Id"] = Guid.NewGuid().ToString();
}
else
{
//如果Id不为空,需要判断Id是否存在
var entity = await _client.Queryable<dynamic>()
.AS(req.TableName)
.Where("Id = @id", new { id = dict["Id"] })
.FirstAsync();
if (entity != null)
var idValue = GetValueIgnoreCase(dict, "Id");
if (string.IsNullOrEmpty(idValue?.ToString()))
{
result.Code = 500;
result.Message = "Id已存在";
return result;
SetValueIgnoreCase(dict, "Id", Guid.NewGuid().ToString());
}
else
{
//如果Id不为空,需要判断Id是否存在
var entity = await _client.Queryable<dynamic>()
.AS(req.TableName)
.Where("Id = @id", new { id = idValue })
.FirstAsync();
if (entity != null)
{
result.Code = 500;
result.Message = "Id已存在";
return result;
}
}
}
//如果有CreateTime字段自动设置
if (dict.ContainsKey("CreateTime"))
//如果有CreateTime字段自动设置(大小写不敏感)
if (ContainsKeyIgnoreCase(dict, "CreateTime"))
{
dict["CreateTime"] = DateTime.Now.ToString();
SetValueIgnoreCase(dict, "CreateTime", DateTime.Now.ToString());
}
// 添加数据
@@ -222,30 +281,44 @@ namespace OpenAuth.App
return result;
}
// 将对象转换为字典
var dict = JsonHelper.Instance.Deserialize<Dictionary<string, Object>>(req.Obj);
// 将对象转换为字典(使用大小写不敏感的反序列化)
var rawDict = JsonConvert.DeserializeObject<Dictionary<string, object>>(req.Obj);
var dict = ToIgnoreCaseDict(rawDict);
// 检查ID是否存在
if (!dict.ContainsKey("Id"))
// 检查ID是否存在(大小写不敏感)
if (!ContainsKeyIgnoreCase(dict, "Id"))
{
result.Code = 500;
result.Message = "更新数据必须包含Id字段";
return result;
}
// 如果有UpdateTime字段自动设置
if (dict.ContainsKey("UpdateTime"))
// 确保字典中有 "Id" 键(用于 SqlSugar 的 WhereColumns
if (!dict.ContainsKey("Id"))
{
dict["UpdateTime"] = DateTime.Now.ToString();
var idValue = GetValueIgnoreCase(dict, "Id");
// 移除原始的小写 id 键
var originalKey = dict.Keys.FirstOrDefault(k => string.Equals(k, "Id", StringComparison.OrdinalIgnoreCase));
if (originalKey != null && originalKey != "Id")
{
dict.Remove(originalKey);
dict["Id"] = idValue;
}
}
// 如果有用户信息,设置更新用户
// 如果有UpdateTime字段自动设置大小写不敏感
if (ContainsKeyIgnoreCase(dict, "UpdateTime"))
{
SetValueIgnoreCase(dict, "UpdateTime", DateTime.Now.ToString());
}
// 如果有用户信息,设置更新用户(大小写不敏感)
var currentUser = _auth.GetCurrentUser();
if (dict.ContainsKey("UpdateUserId") && currentUser != null)
if (ContainsKeyIgnoreCase(dict, "UpdateUserId") && currentUser != null)
{
// 设置更新用户信息
dict["UpdateUserId"] = currentUser.User.Id;
dict["UpdateUserName"] = currentUser.User.Name;
SetValueIgnoreCase(dict, "UpdateUserId", currentUser.User.Id);
SetValueIgnoreCase(dict, "UpdateUserName", currentUser.User.Name);
}
// 更新数据
@@ -387,27 +460,21 @@ namespace OpenAuth.App
try
{
var json = request.Parameters;
// 检查参数名是否存在于JSON中
if (json.Contains($"\"{param.Name}\""))
// 解析完整的JSON对象使用大小写不敏感的字典
var jsonObj = JsonConvert.DeserializeObject<Dictionary<string, object>>(json);
var ignoreCaseDict = ToIgnoreCaseDict(jsonObj);
// 从JSON对象中获取参数值大小写不敏感查找
if (ContainsKeyIgnoreCase(ignoreCaseDict, param.Name))
{
// 解析完整的JSON对象
var jsonObj = JsonHelper.Instance.Deserialize<Dictionary<string, object>>(json);
// 获取参数对应的JSON值并序列化为字符串
var rawValue = GetValueIgnoreCase(ignoreCaseDict, param.Name);
var paramValue = JsonHelper.Instance.Serialize(rawValue);
// JSON对象中获取参数值
if (jsonObj.ContainsKey(param.Name))
{
// 获取参数对应的JSON值并序列化为字符串
var paramValue = JsonHelper.Instance.Serialize(jsonObj[param.Name]);
// 将JSON字符串反序列化为目标类型
var deserializeMethod = typeof(JsonHelper).GetMethod("Deserialize").MakeGenericMethod(param.ParameterType);
paramValues[i] = deserializeMethod.Invoke(JsonHelper.Instance, new object[] { paramValue });
}
else
{
// 参数名存在但获取不到,使用默认值
paramValues[i] = param.HasDefaultValue ? param.DefaultValue : null;
}
// JSON字符串反序列化为目标类型
var deserializeMethod = typeof(JsonHelper).GetMethod("Deserialize").MakeGenericMethod(param.ParameterType);
paramValues[i] = deserializeMethod.Invoke(JsonHelper.Instance, new object[] { paramValue });
}
else
{

View File

@@ -11,8 +11,17 @@ using OpenAuth.App.SSO;
namespace OpenAuth.App.Test
{
class TestDynamicApiApp :TestBase
/// <summary>
/// DynamicApiApp 单元测试
/// 测试表noentity (id varchar(50), name varchar(255), age int)
/// 支持 MySQL 和 SqlServer 数据库
/// 测试大小写混合属性命名
/// </summary>
[TestFixture]
public class TestDynamicApiApp : TestBase
{
private const string TEST_TABLE = "noentity";
public override ServiceCollection GetService()
{
var services = new ServiceCollection();
@@ -28,55 +37,628 @@ namespace OpenAuth.App.Test
return services;
}
#region CRUD
/// <summary>
/// 测试添加数据 - 标准属性名PascalCase
/// </summary>
[Test]
public async Task TestAdd()
public async Task TestAdd_PascalCase()
{
var app = _autofacServiceProvider.GetService<DynamicApiApp>();
var obj = await app.Add(new AddOrUpdateDynamicEntityReq { TableName = "noentity", Obj = "{\"P1\":\"测试\",\"Id\":\"12\"}" });
Console.WriteLine(JsonHelper.Instance.Serialize(obj));
var id = Guid.NewGuid().ToString();
var result = await app.Add(new AddOrUpdateDynamicEntityReq
{
TableName = TEST_TABLE,
Obj = $"{{\"Id\":\"{id}\",\"Name\":\"测试PascalCase\",\"Age\":25}}"
});
Console.WriteLine($"添加结果PascalCase: {JsonHelper.Instance.Serialize(result)}");
Assert.That(result.Code, Is.EqualTo(200), $"添加失败: {result.Message}");
}
/// <summary>
/// 测试添加数据 - 小写属性名camelCase
/// </summary>
[Test]
public async Task TestAdd_CamelCase()
{
var app = _autofacServiceProvider.GetService<DynamicApiApp>();
var id = Guid.NewGuid().ToString();
var result = await app.Add(new AddOrUpdateDynamicEntityReq
{
TableName = TEST_TABLE,
Obj = $"{{\"id\":\"{id}\",\"name\":\"测试camelCase\",\"age\":30}}"
});
Console.WriteLine($"添加结果camelCase: {JsonHelper.Instance.Serialize(result)}");
Assert.That(result.Code, Is.EqualTo(200), $"添加失败: {result.Message}");
}
/// <summary>
/// 测试添加数据 - 大写属性名UPPERCASE
/// </summary>
[Test]
public async Task TestAdd_UpperCase()
{
var app = _autofacServiceProvider.GetService<DynamicApiApp>();
var id = Guid.NewGuid().ToString();
var result = await app.Add(new AddOrUpdateDynamicEntityReq
{
TableName = TEST_TABLE,
Obj = $"{{\"ID\":\"{id}\",\"NAME\":\"测试UPPERCASE\",\"AGE\":35}}"
});
Console.WriteLine($"添加结果UPPERCASE: {JsonHelper.Instance.Serialize(result)}");
Assert.That(result.Code, Is.EqualTo(200), $"添加失败: {result.Message}");
}
/// <summary>
/// 测试添加数据 - 混合大小写属性名MixedCase
/// </summary>
[Test]
public async Task TestAdd_MixedCase()
{
var app = _autofacServiceProvider.GetService<DynamicApiApp>();
var id = Guid.NewGuid().ToString();
// 混合使用不同大小写Id(PascalCase), name(camelCase), AGE(UPPERCASE)
var result = await app.Add(new AddOrUpdateDynamicEntityReq
{
TableName = TEST_TABLE,
Obj = $"{{\"Id\":\"{id}\",\"name\":\"测试MixedCase\",\"AGE\":40}}"
});
Console.WriteLine($"添加结果MixedCase: {JsonHelper.Instance.Serialize(result)}");
Assert.That(result.Code, Is.EqualTo(200), $"添加失败: {result.Message}");
}
/// <summary>
/// 测试获取单条数据
/// </summary>
[Test]
public async Task TestGet()
{
var app = _autofacServiceProvider.GetService<DynamicApiApp>();
var id = Guid.NewGuid().ToString();
// 先添加数据
await app.Add(new AddOrUpdateDynamicEntityReq
{
TableName = TEST_TABLE,
Obj = $"{{\"Id\":\"{id}\",\"Name\":\"测试获取\",\"Age\":28}}"
});
// 获取数据
var result = await app.Get(new QueryDynamicEntityReq
{
TableName = TEST_TABLE,
Id = id
});
Console.WriteLine($"获取结果: {JsonHelper.Instance.Serialize(result)}");
Assert.That(result.Code, Is.EqualTo(200), $"获取失败: {result.Message}");
Assert.That(result.Data, Is.Not.Null, "未找到数据");
var obj = await app.Get(new QueryDynamicEntityReq { TableName = "noentity", Id = "1" });
Console.WriteLine(JsonHelper.Instance.Serialize(obj));
}
/// <summary>
/// 测试获取列表
/// </summary>
[Test]
public async Task TestGetList()
{
var app = _autofacServiceProvider.GetService<DynamicApiApp>();
var obj = await app.GetList(new QueryDynamicListReq { TableName = "noentity", page = 1, limit = 10, key = "" });
Console.WriteLine(JsonHelper.Instance.Serialize(obj));
var result = await app.GetList(new QueryDynamicListReq
{
TableName = TEST_TABLE,
page = 1,
limit = 10,
key = ""
});
Console.WriteLine($"列表查询结果: 总数={result.Count}, 数据条数={result.Data?.Count ?? 0}");
Console.WriteLine($"详细结果: {JsonHelper.Instance.Serialize(result)}");
Assert.That(result.Code, Is.EqualTo(200), $"查询失败: {result.Message}");
}
/// <summary>
/// 测试带关键字搜索的列表查询
/// </summary>
[Test]
public async Task TestInvoke()
public async Task TestGetList_WithKey()
{
var app = _autofacServiceProvider.GetService<DynamicApiApp>();
var id = Guid.NewGuid().ToString();
var searchKey = "搜索测试_" + DateTime.Now.Ticks;
// 先添加测试数据
await app.Add(new AddOrUpdateDynamicEntityReq
{
TableName = TEST_TABLE,
Obj = $"{{\"Id\":\"{id}\",\"Name\":\"{searchKey}\",\"Age\":22}}"
});
// 查询
var result = await app.GetList(new QueryDynamicListReq
{
TableName = TEST_TABLE,
page = 1,
limit = 10,
key = searchKey
});
Console.WriteLine($"带关键字搜索结果: {JsonHelper.Instance.Serialize(result)}");
Assert.That(result.Code, Is.EqualTo(200), $"查询失败: {result.Message}");
Assert.That(result.Count, Is.GreaterThanOrEqualTo(1), "应该至少找到一条数据");
// 清理测试数据
await CleanupTestData(app, id);
}
/// <summary>
/// 测试更新数据 - 标准属性名PascalCase
/// </summary>
[Test]
public async Task TestUpdate_PascalCase()
{
var app = _autofacServiceProvider.GetService<DynamicApiApp>();
var id = Guid.NewGuid().ToString();
// 先添加数据
await app.Add(new AddOrUpdateDynamicEntityReq
{
TableName = TEST_TABLE,
Obj = $"{{\"Id\":\"{id}\",\"Name\":\"原始名称\",\"Age\":20}}"
});
// 更新数据
var result = await app.Update(new AddOrUpdateDynamicEntityReq
{
TableName = TEST_TABLE,
Obj = $"{{\"Id\":\"{id}\",\"Name\":\"更新后PascalCase\",\"Age\":21}}"
});
Console.WriteLine($"更新结果PascalCase: {JsonHelper.Instance.Serialize(result)}");
Assert.That(result.Code, Is.EqualTo(200), $"更新失败: {result.Message}");
// 验证更新结果
var getResult = await app.Get(new QueryDynamicEntityReq { TableName = TEST_TABLE, Id = id });
Console.WriteLine($"更新后数据: {JsonHelper.Instance.Serialize(getResult)}");
}
/// <summary>
/// 测试更新数据 - 小写属性名camelCase
/// </summary>
[Test]
public async Task TestUpdate_CamelCase()
{
var app = _autofacServiceProvider.GetService<DynamicApiApp>();
var id = Guid.NewGuid().ToString();
// 先添加数据
await app.Add(new AddOrUpdateDynamicEntityReq
{
TableName = TEST_TABLE,
Obj = $"{{\"id\":\"{id}\",\"name\":\"原始名称\",\"age\":20}}"
});
// 更新数据
var result = await app.Update(new AddOrUpdateDynamicEntityReq
{
TableName = TEST_TABLE,
Obj = $"{{\"id\":\"{id}\",\"name\":\"更新后camelCase\",\"age\":22}}"
});
Console.WriteLine($"更新结果camelCase: {JsonHelper.Instance.Serialize(result)}");
Assert.That(result.Code, Is.EqualTo(200), $"更新失败: {result.Message}");
}
/// <summary>
/// 测试更新数据 - 混合大小写属性名
/// </summary>
[Test]
public async Task TestUpdate_MixedCase()
{
var app = _autofacServiceProvider.GetService<DynamicApiApp>();
var id = Guid.NewGuid().ToString();
// 先添加数据使用PascalCase
await app.Add(new AddOrUpdateDynamicEntityReq
{
TableName = TEST_TABLE,
Obj = $"{{\"Id\":\"{id}\",\"Name\":\"原始名称\",\"Age\":20}}"
});
// 更新数据(使用混合大小写)
var result = await app.Update(new AddOrUpdateDynamicEntityReq
{
TableName = TEST_TABLE,
Obj = $"{{\"Id\":\"{id}\",\"name\":\"更新后MixedCase\",\"AGE\":23}}"
});
Console.WriteLine($"更新结果MixedCase: {JsonHelper.Instance.Serialize(result)}");
Assert.That(result.Code, Is.EqualTo(200), $"更新失败: {result.Message}");
}
/// <summary>
/// 测试删除单条数据
/// </summary>
[Test]
public async Task TestDelete_Single()
{
var app = _autofacServiceProvider.GetService<DynamicApiApp>();
var id = Guid.NewGuid().ToString();
// 先添加数据
await app.Add(new AddOrUpdateDynamicEntityReq
{
TableName = TEST_TABLE,
Obj = $"{{\"Id\":\"{id}\",\"Name\":\"待删除\",\"Age\":99}}"
});
// 删除数据
var result = await app.Delete(new DelDynamicReq
{
TableName = TEST_TABLE,
Ids = new[] { id }
});
Console.WriteLine($"删除结果: {JsonHelper.Instance.Serialize(result)}");
Assert.That(result.Code, Is.EqualTo(200), $"删除失败: {result.Message}");
// 验证删除结果
var getResult = await app.Get(new QueryDynamicEntityReq { TableName = TEST_TABLE, Id = id });
Assert.That(getResult.Data, Is.Null, "数据应该已被删除");
}
/// <summary>
/// 测试批量删除
/// </summary>
[Test]
public async Task TestDelete_Batch()
{
var app = _autofacServiceProvider.GetService<DynamicApiApp>();
var ids = new[] { Guid.NewGuid().ToString(), Guid.NewGuid().ToString(), Guid.NewGuid().ToString() };
// 添加多条测试数据
foreach (var id in ids)
{
await app.Add(new AddOrUpdateDynamicEntityReq
{
TableName = TEST_TABLE,
Obj = $"{{\"Id\":\"{id}\",\"Name\":\"批量删除测试_{id.Substring(0, 8)}\",\"Age\":50}}"
});
}
// 批量删除
var result = await app.Delete(new DelDynamicReq
{
TableName = TEST_TABLE,
Ids = ids
});
Console.WriteLine($"批量删除结果: {JsonHelper.Instance.Serialize(result)}");
Assert.That(result.Code, Is.EqualTo(200), $"批量删除失败: {result.Message}");
// 验证删除结果
foreach (var id in ids)
{
var getResult = await app.Get(new QueryDynamicEntityReq { TableName = TEST_TABLE, Id = id });
Assert.That(getResult.Data, Is.Null, $"数据 {id} 应该已被删除");
}
}
#endregion
#region CRUD
/// <summary>
/// 测试完整的 CRUD 流程
/// </summary>
[Test]
public async Task TestCRUD_FullFlow()
{
var app = _autofacServiceProvider.GetService<DynamicApiApp>();
var id = Guid.NewGuid().ToString();
Console.WriteLine("=== 开始完整 CRUD 流程测试 ===");
// 1. Create - 创建数据
Console.WriteLine("\n1. 创建数据...");
var addResult = await app.Add(new AddOrUpdateDynamicEntityReq
{
TableName = TEST_TABLE,
Obj = $"{{\"Id\":\"{id}\",\"Name\":\"CRUD测试\",\"Age\":18}}"
});
Console.WriteLine($"创建结果: {JsonHelper.Instance.Serialize(addResult)}");
Assert.That(addResult.Code, Is.EqualTo(200), $"创建失败: {addResult.Message}");
// 2. Read - 读取数据
Console.WriteLine("\n2. 读取数据...");
var getResult = await app.Get(new QueryDynamicEntityReq
{
TableName = TEST_TABLE,
Id = id
});
Console.WriteLine($"读取结果: {JsonHelper.Instance.Serialize(getResult)}");
Assert.That(getResult.Code, Is.EqualTo(200), $"读取失败: {getResult.Message}");
Assert.That(getResult.Data, Is.Not.Null, "数据不应为空");
// 3. Update - 更新数据
Console.WriteLine("\n3. 更新数据...");
var updateResult = await app.Update(new AddOrUpdateDynamicEntityReq
{
TableName = TEST_TABLE,
Obj = $"{{\"Id\":\"{id}\",\"Name\":\"CRUD测试_已更新\",\"Age\":19}}"
});
Console.WriteLine($"更新结果: {JsonHelper.Instance.Serialize(updateResult)}");
Assert.That(updateResult.Code, Is.EqualTo(200), $"更新失败: {updateResult.Message}");
// 验证更新
var getResult2 = await app.Get(new QueryDynamicEntityReq { TableName = TEST_TABLE, Id = id });
Console.WriteLine($"更新后数据: {JsonHelper.Instance.Serialize(getResult2)}");
// 4. Delete - 删除数据
Console.WriteLine("\n4. 删除数据...");
var deleteResult = await app.Delete(new DelDynamicReq
{
TableName = TEST_TABLE,
Ids = new[] { id }
});
Console.WriteLine($"删除结果: {JsonHelper.Instance.Serialize(deleteResult)}");
Assert.That(deleteResult.Code, Is.EqualTo(200), $"删除失败: {deleteResult.Message}");
// 验证删除
var getResult3 = await app.Get(new QueryDynamicEntityReq { TableName = TEST_TABLE, Id = id });
Assert.That(getResult3.Data, Is.Null, "数据应该已被删除");
Console.WriteLine("\n=== 完整 CRUD 流程测试完成 ===");
}
#endregion
#region Invoke
/// <summary>
/// 测试 Invoke 调用 - 获取父级用户
/// </summary>
[Test]
public async Task TestInvoke_GetParent()
{
var app = _autofacServiceProvider.GetService<DynamicApiApp>();
var obj = await app.Invoke(new InvokeDynamicReq { ServiceName = "UserManagerApp", MethodName = "GetParent",
Parameters = "{\"userid\":\"0ceff0f8-f848-440c-bc26-d8605ac858cd\"}" });
Console.WriteLine(JsonHelper.Instance.Serialize(obj));
var result = await app.Invoke(new InvokeDynamicReq
{
ServiceName = "UserManagerApp",
MethodName = "GetParent",
Parameters = "{\"userid\":\"0ceff0f8-f848-440c-bc26-d8605ac858cd\"}"
});
Console.WriteLine($"Invoke GetParent 结果: {JsonHelper.Instance.Serialize(result)}");
}
/// <summary>
/// 测试 Invoke 调用 - 加载用户列表
/// </summary>
[Test]
public async Task TestInvoke2()
public async Task TestInvoke_Load()
{
var app = _autofacServiceProvider.GetService<DynamicApiApp>();
var obj = await app.Invoke(new InvokeDynamicReq {
ServiceName = "UserManagerApp",
MethodName = "Load",
Parameters = "{\"request\":{\"page\":1,\"limit\":10,\"key\":\"dddd\"}}"
});
Console.WriteLine(JsonHelper.Instance.Serialize(obj));
}
var result = await app.Invoke(new InvokeDynamicReq
{
ServiceName = "UserManagerApp",
MethodName = "Load",
Parameters = "{\"request\":{\"page\":1,\"limit\":10,\"key\":\"\"}}"
});
Console.WriteLine($"Invoke Load 结果: {JsonHelper.Instance.Serialize(result)}");
}
/// <summary>
/// 测试 Invoke 调用 - 参数大小写混合
/// </summary>
[Test]
public async Task TestInvoke_MixedCaseParameters()
{
var app = _autofacServiceProvider.GetService<DynamicApiApp>();
// 使用混合大小写的参数
var result = await app.Invoke(new InvokeDynamicReq
{
ServiceName = "UserManagerApp",
MethodName = "Load",
Parameters = "{\"Request\":{\"Page\":1,\"Limit\":10,\"Key\":\"\"}}"
});
Console.WriteLine($"Invoke MixedCase 结果: {JsonHelper.Instance.Serialize(result)}");
}
#endregion
#region
/// <summary>
/// 测试不存在的表
/// </summary>
[Test]
public async Task TestNonExistentTable()
{
var app = _autofacServiceProvider.GetService<DynamicApiApp>();
var result = await app.GetList(new QueryDynamicListReq
{
TableName = "non_existent_table_12345",
page = 1,
limit = 10
});
Console.WriteLine($"查询不存在的表结果: {JsonHelper.Instance.Serialize(result)}");
Assert.That(result.Code, Is.EqualTo(500), "应该返回错误");
Assert.That(result.Message, Does.Contain("表不存在"), "错误信息应包含'表不存在'");
}
/// <summary>
/// 测试更新不包含Id的数据
/// </summary>
[Test]
public async Task TestUpdate_WithoutId()
{
var app = _autofacServiceProvider.GetService<DynamicApiApp>();
var result = await app.Update(new AddOrUpdateDynamicEntityReq
{
TableName = TEST_TABLE,
Obj = "{\"Name\":\"没有Id的更新\",\"Age\":99}"
});
Console.WriteLine($"无Id更新结果: {JsonHelper.Instance.Serialize(result)}");
Assert.That(result.Code, Is.EqualTo(500), "应该返回错误");
Assert.That(result.Message, Does.Contain("Id"), "错误信息应包含'Id'");
}
/// <summary>
/// 测试添加重复Id的数据
/// </summary>
[Test]
public async Task TestAdd_DuplicateId()
{
var app = _autofacServiceProvider.GetService<DynamicApiApp>();
var id = Guid.NewGuid().ToString();
// 第一次添加
await app.Add(new AddOrUpdateDynamicEntityReq
{
TableName = TEST_TABLE,
Obj = $"{{\"Id\":\"{id}\",\"Name\":\"第一次添加\",\"Age\":1}}"
});
// 第二次添加相同Id
var result = await app.Add(new AddOrUpdateDynamicEntityReq
{
TableName = TEST_TABLE,
Obj = $"{{\"Id\":\"{id}\",\"Name\":\"第二次添加\",\"Age\":2}}"
});
Console.WriteLine($"重复Id添加结果: {JsonHelper.Instance.Serialize(result)}");
Assert.That(result.Code, Is.EqualTo(500), "应该返回错误");
Assert.That(result.Message, Does.Contain("Id已存在"), "错误信息应包含'Id已存在'");
// 清理测试数据
await CleanupTestData(app, id);
}
/// <summary>
/// 测试获取不存在的记录
/// </summary>
[Test]
public async Task TestGet_NonExistent()
{
var app = _autofacServiceProvider.GetService<DynamicApiApp>();
var result = await app.Get(new QueryDynamicEntityReq
{
TableName = TEST_TABLE,
Id = "non_existent_id_12345"
});
Console.WriteLine($"获取不存在记录结果: {JsonHelper.Instance.Serialize(result)}");
Assert.That(result.Code, Is.EqualTo(500), "应该返回错误");
Assert.That(result.Message, Does.Contain("未找到"), "错误信息应包含'未找到'");
}
#endregion
#region ID测试
/// <summary>
/// 测试添加数据时自动生成Id
/// </summary>
[Test]
public async Task TestAdd_AutoGenerateId()
{
var app = _autofacServiceProvider.GetService<DynamicApiApp>();
// 不传Id
var result = await app.Add(new AddOrUpdateDynamicEntityReq
{
TableName = TEST_TABLE,
Obj = "{\"Name\":\"自动生成Id测试\",\"Age\":33}"
});
Console.WriteLine($"自动生成Id结果: {JsonHelper.Instance.Serialize(result)}");
Assert.That(result.Code, Is.EqualTo(200), $"添加失败: {result.Message}");
// 查询并验证确实有数据被添加
var listResult = await app.GetList(new QueryDynamicListReq
{
TableName = TEST_TABLE,
page = 1,
limit = 100,
key = "自动生成Id测试"
});
Console.WriteLine($"查询结果: {JsonHelper.Instance.Serialize(listResult)}");
Assert.That(listResult.Count, Is.GreaterThan(0), "应该能查到数据");
}
/// <summary>
/// 测试添加数据时Id为空字符串应自动生成
/// </summary>
[Test]
public async Task TestAdd_EmptyId()
{
var app = _autofacServiceProvider.GetService<DynamicApiApp>();
// 传空Id
var result = await app.Add(new AddOrUpdateDynamicEntityReq
{
TableName = TEST_TABLE,
Obj = "{\"Id\":\"\",\"Name\":\"空Id测试\",\"Age\":34}"
});
Console.WriteLine($"空Id测试结果: {JsonHelper.Instance.Serialize(result)}");
Assert.That(result.Code, Is.EqualTo(200), $"添加失败: {result.Message}");
}
#endregion
#region
/// <summary>
/// 清理测试数据
/// </summary>
private async Task CleanupTestData(DynamicApiApp app, string id)
{
try
{
await app.Delete(new DelDynamicReq
{
TableName = TEST_TABLE,
Ids = new[] { id }
});
}
catch (Exception ex)
{
Console.WriteLine($"清理测试数据失败: {ex.Message}");
}
}
#endregion
}
}