# 通用库 (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

# 🔧 核心类详解

# 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

返回格式示例:

{
    "code": 1,
    "successful": true,
    "msg": "获取成功",
    "errorCode": 0,
    "data": { ... },
    "extra": { }
}
1
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

# 💡 使用示例

# 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. 扩展方法使用

// 字符串扩展
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

# 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

# 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

# 🔍 常见问题

# 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

# 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

# Q3: Check.NotNull 和 if (obj == null) 有什么区别?

Check.NotNull 的优势:

  1. 自动抛出标准异常(ArgumentNullException)
  2. 包含参数名,便于调试
  3. 支持自定义错误消息
  4. 代码更简洁

对比:

// 传统方式
if (request == null)
    throw new ArgumentNullException(nameof(request), "请求不能为空");

// Check 方式(推荐)
Check.NotNull(request, nameof(request), "请求不能为空");
1
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

# 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

# 📚 相关文档


# 🔗 参考链接


最后更新: 2024-09-20