# 通用库 (01_Utils)
最后更新: 2024-09-20
# 📚 概述
DarkM 通用库是框架的基础支撑库,提供结果模型、参数检查、扩展方法、工具类、枚举类型等核心功能。所有其他模块都依赖此库。
源代码位置: DarkM/src/Framework/Utils
# 🏗️ 模块架构
# 完整目录结构
Utils/
├── Utils.Core/ # 核心库
│ ├── Result/ # 结果模型
│ │ ├── ResultModel.cs # 通用结果模型
│ │ ├── ResultModel{T}.cs # 泛型结果模型
│ │ ├── IResultModel.cs # 结果接口
│ │ ├── IResultModel{T}.cs # 泛型结果接口
│ │ ├── QueryResultModel.cs # 查询结果(分页)
│ │ └── ...
│ │
│ ├── Check.cs # 参数检查工具类
│ │
│ ├── Extensions/ # 扩展方法
│ │ ├── CommonExtensions.cs # 通用转换扩展
│ │ ├── StringExtensions.cs # 字符串扩展
│ │ ├── DateTimeExtensions.cs # 日期时间扩展
│ │ ├── EnumExtensions.cs # 枚举扩展
│ │ ├── ListExtensions.cs # 列表扩展
│ │ ├── GuidExtensions.cs # GUID 扩展
│ │ └── ...
│ │
│ ├── Helpers/ # 工具类
│ │ ├── AssemblyHelper.cs # 程序集帮助类
│ │ ├── FileUtils.cs # 文件帮助类
│ │ ├── JSONUtils.cs # JSON 工具
│ │ ├── DateTimeHelper.cs # 日期帮助类
│ │ └── ...
│ │
│ ├── Enums/ # 枚举类型
│ │ ├── Status.cs # 状态枚举
│ │ ├── Whether.cs # 是否枚举
│ │ ├── Sex.cs # 性别枚举
│ │ └── ...
│ │
│ └── Encrypt/ # 加密类
│ ├── DesEncrypt.cs # DES 加解密
│ ├── MD5Encrypt.cs # MD5 加密
│ ├── AesEncrypt.cs # AES 加解密
│ └── RsaEncrypt.cs # RSA 加解密
│
└── Utils.Mvc/ # MVC 扩展库
├── Extensions/ # MVC 扩展
│ ├── HttpContextExtensions.cs # HTTP 上下文扩展
│ └── HttpRequestExtensions.cs # HTTP 请求扩展
│
└── Helpers/ # MVC 帮助类
├── IpHelper.cs # IP 帮助类
├── FileUploadHelper.cs # 文件上传帮助类
└── HttpClientHelper.cs # HTTP 客户端帮助类
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
# 🔧 核心类详解
# 1. ResultModel(结果模型)
文件位置: Result/ResultModel.cs
namespace DarkM
{
/// <summary>
/// 返回结果
/// </summary>
public class ResultModel<T> : IResultModel<T>
{
/// <summary>
/// 处理是否成功
/// </summary>
[JsonIgnore]
public bool Successful { get; set; }
/// <summary>
/// 错误信息
/// </summary>
public string Msg { get; set; }
/// <summary>
/// 状态码(1=成功,0=失败)
/// </summary>
public int Code { get; set; }
/// <summary>
/// 错误码
/// </summary>
public int ErrorCode { get; set; } = 0;
/// <summary>
/// 返回数据
/// </summary>
public T Data { get; set; }
/// <summary>
/// 成功
/// </summary>
public IResultModel<T> Success(T data = default, string msg = "success", int errorCode = 0)
{
Successful = true;
Data = data;
Msg = msg;
ErrorCode = errorCode;
return this;
}
/// <summary>
/// 失败
/// </summary>
public IResultModel<T> Failed(string msg = "failed", int errorCode = 1000, T data = default)
{
Successful = false;
Msg = msg;
ErrorCode = errorCode;
Data = data;
return this;
}
}
/// <summary>
/// 返回结果(静态工具类)
/// </summary>
public static class ResultModel
{
/// <summary>
/// 成功(带数据)
/// </summary>
public static IResultModel Success<T>(T data, string msg = "success", int errorCode = 0)
{
return new ResultModel<T>().Success(data, msg, errorCode);
}
/// <summary>
/// 成功(无数据)
/// </summary>
public static IResultModel Success(string msg = "success")
{
return Success<string>(null, msg);
}
/// <summary>
/// 失败
/// </summary>
public static IResultModel Failed<T>(string msg = null, int errorCode = 1000, T data = default)
{
return new ResultModel<T>().Failed(msg ?? "failed", errorCode, data);
}
/// <summary>
/// 数据已存在
/// </summary>
public static IResultModel HasExists => Failed("数据已存在", 1001);
/// <summary>
/// 数据不存在
/// </summary>
public static IResultModel NotExists => Failed("数据不存在", 1002);
/// <summary>
/// 无权限
/// </summary>
public static IResultModel NoPermission => Failed("无权限", 403);
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
返回格式示例:
{
"code": 1,
"successful": true,
"msg": "获取成功",
"errorCode": 0,
"data": { ... },
"extra": { }
}
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
# 2. Check(参数检查)
文件位置: Check.cs
namespace DarkM
{
/// <summary>
/// 参数检查工具类
/// </summary>
public class Check
{
/// <summary>
/// 检测对象是否为空
/// </summary>
public static void NotNull<T>(T obj, string parameterName, string message = null)
{
if (ReferenceEquals(obj, null))
throw new ArgumentNullException(parameterName, message ?? $"{parameterName} is null");
}
/// <summary>
/// 检测字符串是否为空
/// </summary>
public static void NotNull(string obj, string parameterName, string message = null)
{
if (string.IsNullOrWhiteSpace(obj))
throw new ArgumentNullException(parameterName, message ?? $"{parameterName} is null");
}
/// <summary>
/// 检测集合是否不为空且包含内容
/// </summary>
public static void Collection<T>(IList<T> list, string parameterName)
{
NotNull(list, parameterName);
if (!list.Any())
throw new ArgumentException("集合不包含任何内容", parameterName);
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
# 💡 使用示例
# 1. Controller 返回结果
[ApiController]
[Route("api/[controller]")]
public class UsersController : ControllerBase
{
private readonly IUserService _userService;
public UsersController(IUserService userService)
{
_userService = userService;
}
/// <summary>
/// 获取用户
/// </summary>
[HttpGet("{id}")]
public IResultModel<UserDto> Get(int id)
{
var user = _userService.GetById(id);
if (user == null)
return ResultModel.NotExists;
return ResultModel.Success(user);
}
/// <summary>
/// 创建用户
/// </summary>
[HttpPost]
public async Task<IResultModel> Create([FromBody] CreateUserRequest request)
{
Check.NotNull(request, nameof(request));
Check.NotNull(request.UserName, nameof(request.UserName));
if (await _userService.ExistsByUserName(request.UserName))
return ResultModel.HasExists;
await _userService.CreateAsync(request);
return ResultModel.Success();
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
# 2. 扩展方法使用
// 字符串扩展
string str = "";
if (str.IsNull()) { /* 处理空字符串 */ }
"hello world".ContainsIgnoreCase("WORLD"); // true
"UserName".Camel(); // userName
"password".ToMd5(); // MD5 加密
// 日期扩展
DateTime.Now.GetDayStart(); // 当天 00:00:00
DateTime.Now.ToTimestamp(); // 时间戳
dateTime.ToRelativeTimeString(); // "5 分钟前"
// 枚举扩展
Sex.Boy.ToDescription(); // "男"
Sex.ToResult(); // 转换为选项列表 [{ Label: "男", Value: 0 }, ...]
// 集合扩展
list.IsNullOrEmpty(); // 判断是否为空
list.Page(1, 20); // 分页
list.ToCommaDelimited(); // "1,2,3,4,5"
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 3. 工具类使用
// AssemblyHelper
var assemblies = AssemblyHelper.LoadByNameContainsString("DarkM");
// JSONUtils
var json = JSONUtils.ToJson(obj);
var obj = JSONUtils.FromJson<T>(json);
// FileUtils
var sizeStr = FileUtils.GetFileSizeString(1024 * 1024); // "1.00 MB"
// DateTimeHelper
var timestamp = DateTimeHelper.GetTimestamp();
var dateTime = DateTimeHelper.TimestampToDateTime(timestamp);
// ZipHelper
ZipHelper.ZipFile(sourcePath, zipPath);
ZipHelper.ExtractToDirectory(zipPath, extractPath);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 4. 加密类使用
// DES
var encrypted = DesEncrypt.Encrypt("明文", "密钥");
var decrypted = DesEncrypt.Decrypt("密文", "密钥");
// MD5
var md5 = MD5Encrypt.Encrypt("password"); // 小写
var md5Upper = MD5Encrypt.EncryptUpper("password"); // 大写
// AES
var encrypted = AesEncrypt.Encrypt("明文", "密钥");
var decrypted = AesEncrypt.Decrypt("密文", "密钥");
// RSA
var encrypted = RsaEncrypt.EncryptByPublicKey("明文", publicKey);
var decrypted = RsaEncrypt.DecryptByPrivateKey("密文", privateKey);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 🔍 常见问题
# Q1: ResultModel 的 Code 和 Successful 有什么关系?
关系说明:
Successful是内部布尔标志Code是对外输出的状态码(1=成功,0=失败)Code的值由Successful自动计算
示例:
var result = ResultModel.Success<User>(user);
// result.Successful = true
// result.Code = 1(自动计算)
var result2 = ResultModel.Failed("错误");
// result2.Successful = false
// result2.Code = 0(自动计算)
1
2
3
4
5
6
7
2
3
4
5
6
7
# Q2: 如何选择 Success 和 SuccessT?
区别:
Success<T>()- 返回IResultModel(非泛型)SuccessT<T>()- 返回IResultModel<T>(泛型)
使用场景:
// 需要泛型时(推荐)
public IResultModel<User> GetUser()
{
return ResultModel.SuccessT<User>(user);
}
// 不需要泛型时
public IResultModel GetUser()
{
return ResultModel.Success(user);
}
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
# Q3: Check.NotNull 和 if (obj == null) 有什么区别?
Check.NotNull 的优势:
- 自动抛出标准异常(ArgumentNullException)
- 包含参数名,便于调试
- 支持自定义错误消息
- 代码更简洁
对比:
// 传统方式
if (request == null)
throw new ArgumentNullException(nameof(request), "请求不能为空");
// Check 方式(推荐)
Check.NotNull(request, nameof(request), "请求不能为空");
1
2
3
4
5
6
2
3
4
5
6
# Q4: 如何获取枚举的所有选项?
方法:
// 获取结果列表(用于下拉框)
var statusList = EnumExtensions.ToResultList<Status>();
// 返回:[{ Value: 0, Label: "禁用" }, { Value: 1, Label: "启用" }]
// 获取字典
var statusDict = EnumExtensions.ToDictionary<Status>();
// 返回:{ 0: "禁用", 1: "启用" }
// 获取描述
var desc = Status.Enabled.GetDescription(); // "启用"
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
# Q5: 如何使用文件上传帮助类?
解决方案:
// 配置上传选项
var options = new FileUploadOptions
{
UploadPath = "/uploads",
UrlPrefix = "https://example.com",
MaxFileSize = 10 * 1024 * 1024, // 10MB
AllowedExtensions = new[] { ".jpg", ".png", ".pdf" }
};
// 上传文件
var result = await FileUploadHelper.UploadAsync(file, options);
// 返回结果
{
"success": true,
"fileName": "test.jpg",
"filePath": "/uploads/2026/03/03/test.jpg",
"fileUrl": "https://example.com/uploads/2026/03/03/test.jpg",
"fileSize": 102400
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 📚 相关文档
# 🔗 参考链接
- 源代码 (opens new window) -
src/Framework/Utils - Newtonsoft.Json 文档 (opens new window)
最后更新: 2024-09-20