Liwendong.Utility
3.3.1
See the version list below for details.
dotnet add package Liwendong.Utility --version 3.3.1
NuGet\Install-Package Liwendong.Utility -Version 3.3.1
<PackageReference Include="Liwendong.Utility" Version="3.3.1" />
<PackageVersion Include="Liwendong.Utility" Version="3.3.1" />
<PackageReference Include="Liwendong.Utility" />
paket add Liwendong.Utility --version 3.3.1
#r "nuget: Liwendong.Utility, 3.3.1"
#:package Liwendong.Utility@3.3.1
#addin nuget:?package=Liwendong.Utility&version=3.3.1
#tool nuget:?package=Liwendong.Utility&version=3.3.1
Liwendong.Utility
通用辅助工具集合,一个包覆盖 .NET Framework 老项目到 .NET 8 新项目。
支持的目标框架
| 目标框架 | 说明 |
|---|---|
net8.0 |
主要开发与推荐目标 |
netcoreapp3.1 |
维护中的存量项目 |
net48 |
.NET Framework 4.8 |
net47 |
.NET Framework 4.7 |
net46 |
.NET Framework 4.6 |
net451 |
.NET Framework 4.5.1 |
多框架差异通过条件编译处理,同一份调用代码在六个框架下均可编译。 已知的平台相关限制见下方「平台与多版本注意事项」。
安装
dotnet add package Liwendong.Utility
工具类一览
| 类别 | 类 | 说明 |
|---|---|---|
| 配置 | ConfigHelper |
统一读取配置(Core 读 appsettings.json,Framework 读 App.config) |
| 缓存 | CacheHelper |
内存缓存(Core 用 IMemoryCache,Framework 用 MemoryCache) |
| JSON | JsonHelper |
序列化 / 反序列化 / JSONPath 取值 / 深拷贝 |
| 加密 | SecurityHelper |
MD5、SHA、HMAC、DES、AES、RSA、Base64、PBKDF2、AES-GCM |
| 证书 | CertHelper |
X509 证书读取与导出 |
| HTTP | HttpHelper |
基于 HttpWebRequest 的同步请求(含回调式异步) |
| HTTP | HttpClientHelper |
推荐,基于 HttpClient 的 Task 异步请求,支持 CancellationToken |
| 字符串 | StringHelper |
字符串处理与扩展 |
| 转换 | ConvertHelper |
类型转换 |
| 编码 | EncodingHelper |
编码识别与转换 |
| 正则 | RegexHelper |
常用正则常量与匹配/提取/替换 |
| 压缩 | CompressHelper |
GZip、Deflate、ZIP |
| 网络 | IpHelper |
IP 校验、内外网判断、整数互转 |
| 图片 | ImageHelper |
图片处理(仅 Windows) |
| 条码 | BarCodeHelper |
Code128 一维码(仅 Windows) |
| 日志 | LogHelper |
文件日志 |
| IO | IOHelper |
文件与目录操作 |
| 反射 | ReflectionHelper |
程序集与类型扫描 |
| 时间 | DateTimeHelper |
日期时间处理 |
| 随机 | RandomHelper |
随机数与随机字符串 |
| ID | Snowflake |
雪花算法分布式 ID |
| 邮件 | EmailHelper |
SMTP 邮件发送(SmtpClient / MailKit 双实现) |
| 线程 | ThreadingHelper |
线程池与 Mutex |
| XML | XmlHelper |
XML 序列化与操作 |
| Web | WebHelper / CookieHelper / HtmlHelper |
Web 相关辅助 |
| 校验 | ValidationHelper |
基于 DataAnnotations 的模型校验 |
| 签名 | ApiHelper |
接口签名生成与校验 |
使用示例
配置读取(无配置文件也不会崩)
// 缺少 appsettings.json 时返回默认值,不抛异常(net451 与 net8.0 行为一致)
var size = ConfigHelper.GetValue("LogFileMaxSize", 2M);
var conn = ConfigHelper.GetConnectionStrings<string>("Default");
// 可判断配置是否真的加载成功
if (!ConfigHelper.HasConfiguration)
{
// 输出诊断信息
}
异步 HTTP 请求
// HttpClientHelper:Task-based 异步,支持取消
var json = await HttpClientHelper.GetStringAsync(url, cancellationToken: cts.Token);
var model = await HttpClientHelper.GetJsonAsync<MyModel>(url);
var result = await HttpClientHelper.PostJsonAsync(url, new { name = "test" });
// HttpHelper 的异步重载
var info = await HttpHelper.GetAsync(url, "a=1");
缓存
CacheHelper.Set("key", value); // 默认滑动过期 20 分钟
var v = CacheHelper.GetOrAdd("key", () => LoadData()); // 不存在时自动生成
口令哈希与现代加密
var hash = SecurityHelper.HashPassword("mypassword"); // PBKDF2
bool ok = SecurityHelper.VerifyPassword("mypassword", hash);
// AES-256-GCM(仅 net5.0+,密文被篡改会返回 null)
var cipher = SecurityHelper.AesGcmEncrypt("secret", key);
var plain = SecurityHelper.AesGcmDecrypt(cipher, key);
邮件发送(MailKit,推荐)
// 1. 便捷异步:自动按发件人域名推断 SMTP(内置 163/qq/gmail/aliyun 等域名表)
var (ok, msg) = await EmailHelper.SendEmailAsync(
toEmail: "receiver@example.com",
subject: "订单通知",
htmlBody: "<h1>你好</h1>",
fromEmail: "sender@qq.com",
password: "授权码",
attachments: new[] { @"D:\report.xlsx" });
// 2. 完整控制:抄送、密送、纯文本备选、加密方式、超时、取消令牌
var message = new EmailMessage
{
FromAddress = "sender@example.com",
FromDisplayName = "系统通知",
Subject = "中文主题不会乱码",
HtmlBody = "<b>HTML 正文</b>",
TextBody = "纯文本备选",
Priority = MimeKit.MessagePriority.Urgent,
AttachmentPaths = { @"D:\a.pdf" }
};
message.To.Add("a@example.com");
message.Cc.Add("b@example.com");
message.Bcc.Add("c@example.com");
var options = new SmtpOptions("smtp.example.com", "sender@example.com", "授权码", 587)
{
SocketOptions = MailKit.Security.SecureSocketOptions.StartTls,
Timeout = 30000
};
using var cts = new CancellationTokenSource(TimeSpan.FromSeconds(30));
var result = await EmailHelper.SendEmailAsync(message, options, cts.Token);
// 3. 同步版本(内部以线程池线程执行,不会因同步上下文死锁)
var sync = EmailHelper.SendEmailByMailKit(message, options);
新旧实现对比:
SendEmail(SmtpClient) |
SendEmailAsync / SendEmailByMailKit(MailKit) |
|
|---|---|---|
| 异步 / 取消 | 不支持 | 原生 Task + CancellationToken |
| 中文主题 | 需手动处理编码 | 标准 MIME 编码,不乱码 |
| 收件人 | 单个 | 收件人 / 抄送 / 密送 多个 |
| 附件 | 单个 | 多个 |
| 跨平台 | Windows 行为有差异 | 各平台一致 |
| 维护状态 | 微软标记 SYSLIB0016 过时 | 官方推荐替代 |
SendEmail(基于System.Net.Mail.SmtpClient)保留不变,现有代码无需迁移; 新代码建议使用 MailKit 版本。
JSON
var json = JsonHelper.Serialize(obj);
var obj = JsonHelper.Deserialize<MyModel>(json);
var name = JsonHelper.GetValue(json, "data.list[0].name");
平台与多版本注意事项
System.Drawing 仅 Windows:
ImageHelper、BarCodeHelper、Gif/*依赖System.Drawing.Common,已标注[SupportedOSPlatform("windows")]。 在 Linux / 容器环境调用会抛PlatformNotSupportedException,请改用 ImageSharp / SkiaSharp。AES-GCM 全框架可用:
SecurityHelper.AesGcmEncrypt/AesGcmDecrypt在 net5+ 与 netcoreapp3.1 使用平台原生AesGcm,在 net451/net46/net48 走 BouncyCastle 实现,密文格式统一(Base64(nonce12+tag16+cipher)),跨框架互操作。 PBKDF2 全框架可用。X509Certificate2 的释放:该类型直到 .NET Framework 4.6 才实现
IDisposable, 因此 net451 下无法使用using,库内部已按条件编译统一处理。配置键的命名:netcore 下
GetAppSettings("X")读取AppSettings:X节点, net451 下读取 App.config 的<appSettings>配置节,两者配置结构不同, 跨框架迁移时需注意。推荐使用GetValue配合统一的配置结构。
重要变更(V3.1.0)
- 修复:
ConfigHelper在缺少 appsettings.json 时抛TypeInitializationException, 导致控制台 / 类库 / 单元测试等非 ASP.NET 环境下整个类不可用,并连带使LogHelper静默失效。 现改为延迟构建 + 缺失时回退空配置。 - 修复:
ImageHelper.AddFontWaterMark判空逻辑写反,调用方传入的水印文字被强制覆盖。 - 修复:
ApiHelper.VerifyRequestSignature转发时漏传vaildSeconds,导致时间戳有效期校验被忽略。 - 修复:
Snowflake的状态字段误声明为static,同进程多实例会互相覆盖产生重复 ID。 - 修复:
EmailHelper默认端口误写为 578(修正为 587),并补齐资源释放。 - 修复:
CertHelper.GetPrivateKey/GetPrivateKeyFromStore为半成品(前者丢弃结果,后者恒定返回空串)。 - 更新:
CertHelper公钥 / 私钥读取改用GetRSAPublicKey()/GetRSAPrivateKey()(PublicKey.Key、PrivateKey已在 .NET 8 标记为 SYSLIB0027 / SYSLIB0028 过时)。 net451 无新 API,仍走旧路径;非 RSA 证书(如 DSA)自动回退旧路径,行为不变。 - 安全:移除
CertHelper中硬编码的默认加密串,以及SecurityHelper内置的 DES 默认密钥liwen528(公开代码中硬编码密钥等同于明文)。未显式设置密钥时DESEncrypt/DESDecrypt会抛出明确异常。 - 命名:
EncodingHepler→EncodingHelper、ValidatetionHelper→ValidationHelper、ASE_Encrypt/ASE_Decrypt→AES_Encrypt/AES_Decrypt、GetPlulicKey→GetPublicKey。 旧名称保留并标记[Obsolete],现有代码仍可编译,建议尽快迁移。 - 破坏性:
ConfigHelper.GetEntity<T>在 net451 下的泛型约束由class, IConfigurationSectionHandler, new()放宽为class, new(),与 netcore 保持一致。 - 新增:
EmailHelper增加基于 MailKit 的SendEmailAsync/SendEmailByMailKit, 支持异步与取消令牌、多收件人、抄送与密送、多附件、显式加密策略与超时控制。 原SendEmail(SmtpClient)保持不变,现有代码无需迁移。 - 安全:
SecurityHelper.HashPassword文档声明为 PBKDF2-HMAC-SHA256, 但此前调用Rfc2898DeriveBytes三参数重载,实际使用的是 SHA1。 现改为自行实现 PBKDF2-HMAC-SHA256(已通过标准测试向量与 .NET 内置实现交叉验证)。 之所以不直接用带HashAlgorithmName的重载,是因为该重载在 net451/net46 上不存在, 按框架分档调用会导致同一口令在不同框架下哈希不同、换框架后存量口令全部校验失败。 哈希串格式相应升级为版本.迭代次数.盐.哈希,旧的 3 段格式仍可校验通过。
更新日志
3.3.1 (2026-10-17)
- 修复:
HttpHelper.SetCer不再自动关闭 HTTPS 证书校验(进程级),仅显式SkipCertificateValidation(true)时跳过校验。 - 修复:Core 分支
WebHelper.GetUserAgent/UserAgent()读取头名笔误HeaderUserAgent,恢复为User-Agent;LogHelper.PrepareLogWriteParameter判空条件写反(为空时回退 Request URL);PrepareLogInfo在logParms == null时空引用。 - 修复:
ConvertHelper.FormatTime无-分支AppendFormat("{0}")必抛 FormatException,重写为按 4/6/8 位数字分段拼接;To*系列o == null时返回_default;ToDateTimeNull解析失败返回 null;ToDataTable<T>支持Nullable<T>列;DataTableConvertToJson改用 Newtonsoft 序列化(补齐转义);CompareList多重集比较错误;CutDecimalWithN与Extension.Struct系列改用 InvariantCulture 并消除(decimal)(int)溢出;ToSortedObjectDictionary类型判断笔误;EntityParametersAssignment三重载抽取CopyProperties核心并以Nullable.GetUnderlyingType解析可空类型(修复非 mscorlib 类型 NRE)。 - 修复:
BarCodeHelperCode128 码表第 76 项 Code128B 值"I"更正为"l";RandomHelper.GetOneNumber永不生成'0';GuidTo16String溢出且长度不固定(改为 Guid 前 8 字节 hex);GetObjectByWeight重写为标准加权随机(Weight<=0 不参与);RandomProbability死循环/重复 key/越界;GetRandomNation硬编码数量。 - 修复:
AttributeHelper/ReflectionHelper(过滤条件写反、缓存键冲突与污染、BadImageFormatException、多处判空)/ExpressionHelper.GetName不处理装箱UnaryExpression/CacheHelper值类型命中误判与GetOrAdd非原子、Clear遍历中删除/CertHelper证书库未关闭与校验漏 return/IOHelperMIME 校验笔误、扩展名正则、gzip ISIZE OOM、上传短读与边界、magic 比较歧义、GC.Collect/ImageHelper.ToImage关流后 GDI+ 错误、验证码 GDI 泄漏/CompressHelper.UnZipZip Slip 防护/EmailHelper集合判空与域名后缀匹配/Extension.Number.ToString(decimals)格式串长度/Extension.IEnumerable.AnyData等问题。 - 修复:
ApiHelper时间戳校验改为双向时间窗、同 key 覆盖不再抛异常;验签比较改为定长时间比较。说明:GetResponseMysign的 MD5 签名算法仅保留兼容用途,新系统请改用更强的摘要算法。 - 优化:
RandomHelper线程安全随机源([ThreadStatic]);HttpHelper.Post_MultimediaHttpClientAsync复用共享HttpClient并改为真异步;LogHelper.EndWrireLog吞异常改为写入 Trace;StringHelper静态构造注册CodePagesEncodingProvider(netcore 下 GB2312 拼音可用,netcoreapp3.1 补引System.Text.Encoding.CodePages)。
V3.3.*
- [3.3.0] 安全加固与缺陷修复
HtmlHelper.EnsureOnlyAllowedHtml重写为属性级白名单过滤,防 XSS 注入;FormatText异常改为记日志;BBCodeHelper链接/图片地址经HtmlHelper.GetSafeUrl校验,拒绝javascript:等伪协议;引用作者名 HTML 编码;XmlHelper全部XmlDocument禁用XmlResolver并在反序列化入口拒绝 DTD(防 XXE);HttpHelper.SetHttpsRequest不再默认关闭证书校验,改为显式SkipCertificateValidation()开启;TLS 默认加入 Tls13(net8);- 验证码与
GenerateCheckCode改用密码学随机数(新增RandomHelper.GetSecureRandomValue);DES_Generator密钥改用 CSPRNG 生成; SecurityHelper:AES 非 ECB 模式强制校验 16 字节 IV(缺省即抛ArgumentException,杜绝随机 IV 解密失败);VerifyPassword增加 PBKDF2 迭代次数上限防 DoS;EncodeBase64移除静默降级 catch;- AES-GCM 跨框架:netcoreapp3.1 启用原生实现,net451/net46/net48 新增 BouncyCastle 实现,密文跨框架互通(已验证 net48↔net8 回环);
- Cookie(
CookieHelper/CookieServices)补HttpOnly/Secure/SameSite=Lax;修复 Core 分支isEncrypt参数被丢弃的 bug; WebHelper.GetIP改用X-Forwarded-For/X-Real-IP头并修复 REMOTE_ADDR 误用;新增NormalizeClientIp规范化 IPv4-mapped 地址;- HttpClient 迁移(SYSLIB0014):
EncodingHelper.GetEncodingName(Uri)、IOHelper.GetRemoteFileLength、WebHelper.BuildStaticPage改用HttpClientHelper,消除 .NET 6+ 过时警告(非 2xx 异常类型由WebException变为HttpRequestException); - 修复:
ConvertHelper.ToUInt16(object)返回类型int→UInt16;ToFileSizeText单位索引越界;DateTimeHelper.ToUnixTimeSecondsnet451 返回类型int→long、GetTimeRankOfTheWeek周日归属错误;Snowflake负 machineId 改为抛ArgumentOutOfRangeException(原静默置 0 会产生重复 ID);CompressHelper.ZipSingleFile/ZipDirectory误把文件路径当目录创建; - 资源与稳健性:
IOHelper.ValidateFileBinaryCode不再关闭调用方传入的流(leaveOpen);EncodingHelper.GetEncodingName(Uri)响应释放改为using;HttpHelper.PostAsync/Post_WebClientAsync修复回调泄漏与未处理异常;IOHelper.GetSizeName复用ConvertHelper.ToFileSizeText(输出格式统一为1.00KB); - 弱算法(DES/默认 ECB 模式/MD5 签名/HmacSHA1)仅补文档警示,密钥派生与默认行为保持兼容,存量数据可正常解密。
V3.2.*
- [3.2.2] ��
ThreadingHelper.RunMutex��- ����
lockTaken������δ����������ʱ���ٵ���ReleaseMutex������ApplicationException���� - ǰ�γ����߳�/���̱�����
AbandonedMutexException��ʱ��ȷ���ѻ���������ִ�� Action�����������ϱ��β����� - �쳣ֱ�Ӵ��������پ�
throw ception������ԭʼ��ջ��ʧ���Ƴ��˽������ӳ������ظ� catch��
- ����
V3.1.*
- [3.1.1] 新增基于 MailKit 的邮件发送(异步 / 取消令牌 / 抄送密送 / 多附件);
修正
HashPassword实际使用 SHA1 与文档不符的问题,改为全平台一致的 PBKDF2-HMAC-SHA256; 修复EncodingHelper.cs中 1335 处中文注释乱码(2026-08-30 提交误将 GBK 按 UTF-8 转码所致)。 - [3.1.0] 修复 ConfigHelper 跨版本崩溃链与多项缺陷;新增 JsonHelper / CacheHelper / CompressHelper / RegexHelper / IpHelper / HttpClientHelper;补充异步 API 与 CancellationToken; 新增 PBKDF2 与 AES-GCM;补全 README。
V3.0.*
- [3.0.0] 支持 .NET 8.0
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
| .NET Core | netcoreapp3.1 is compatible. |
| .NET Framework | net451 is compatible. net452 was computed. net46 is compatible. net461 was computed. net462 was computed. net463 was computed. net47 is compatible. net471 was computed. net472 was computed. net48 is compatible. net481 was computed. |
-
.NETCoreApp 3.1
- Liwendong.Resources (>= 2.0.1)
- MailKit (>= 4.18.1)
- Microsoft.AspNetCore.Http (>= 2.2.2)
- Microsoft.AspNetCore.Http.Abstractions (>= 2.2.0)
- Microsoft.Data.SqlClient (>= 5.2.3)
- Microsoft.Extensions.Caching.Memory (>= 3.1.1)
- Microsoft.Extensions.Configuration (>= 3.1.1)
- Microsoft.Extensions.Configuration.Abstractions (>= 3.1.1)
- Microsoft.Extensions.Configuration.Binder (>= 3.1.1)
- Microsoft.Extensions.Configuration.Json (>= 3.1.1)
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 3.1.1)
- Newtonsoft.Json (>= 13.0.3)
- System.Drawing.Common (>= 6.0.0)
- System.Text.Encoding.CodePages (>= 10.0.0)
-
.NETFramework 4.5.1
- Liwendong.Resources (>= 2.0.1)
- MailKit (>= 2.15.0)
- Newtonsoft.Json (>= 13.0.3)
-
.NETFramework 4.6
- Liwendong.Resources (>= 2.0.1)
- MailKit (>= 2.15.0)
- Newtonsoft.Json (>= 13.0.3)
-
.NETFramework 4.7
- Liwendong.Resources (>= 2.0.1)
- MailKit (>= 4.18.1)
- Newtonsoft.Json (>= 13.0.3)
-
.NETFramework 4.8
- Liwendong.Resources (>= 2.0.1)
- MailKit (>= 4.18.1)
- Newtonsoft.Json (>= 13.0.3)
-
net8.0
- Liwendong.Resources (>= 2.0.1)
- MailKit (>= 4.18.1)
- Microsoft.AspNetCore.Http (>= 2.2.2)
- Microsoft.AspNetCore.Http.Abstractions (>= 2.2.0)
- Microsoft.Data.SqlClient (>= 5.2.3)
- Microsoft.Extensions.Caching.Memory (>= 8.0.1)
- Microsoft.Extensions.Configuration (>= 8.0.0)
- Microsoft.Extensions.Configuration.Binder (>= 8.0.2)
- Microsoft.Extensions.Configuration.Json (>= 8.0.1)
- Newtonsoft.Json (>= 13.0.3)
- System.Text.Encoding.CodePages (>= 8.0.0)
NuGet packages (4)
Showing the top 4 NuGet packages that depend on Liwendong.Utility:
| Package | Downloads |
|---|---|
|
Liwendong.Frameworks
基础框架 |
|
|
Liwendong.Frameworks.Services.API
服务API管理 |
|
|
Liwendong.Wexin.MP.SDK
微信公众号辅助SDK |
|
|
Liwendong.Frameworks.Data.DapperExtend
Dapper扩展 |
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 3.3.3 | 171 | 10/23/2026 |
| 3.3.2 | 91 | 10/22/2026 |
| 3.3.1 | 336 | 10/20/2026 |
| 3.2.0 | 109 | 10/8/2026 |
| 2.9.3 | 275 | 5/9/2026 |
| 2.9.2 | 186 | 2/15/2026 |
| 2.9.1 | 353 | 11/27/2025 |
| 2.8.11 | 316 | 11/24/2025 |
| 2.8.10 | 756 | 11/20/2025 |
| 2.8.9 | 232 | 9/27/2025 |
| 2.8.8 | 431 | 9/22/2025 |
| 2.8.7 | 424 | 9/17/2025 |
| 2.8.6 | 339 | 9/15/2025 |
| 2.8.5 | 329 | 9/4/2025 |
| 2.8.3 | 842 | 9/1/2025 |
| 2.8.2 | 469 | 8/26/2025 |
| 2.8.1 | 252 | 8/23/2025 |
| 2.8.0 | 346 | 8/13/2025 |
| 2.7.3 | 301 | 8/13/2025 |
| 2.7.2 | 475 | 8/13/2025 |