RuoVea.ExFilter
9.0.0.2
There is a newer version of this package available.
See the version list below for details.
See the version list below for details.
dotnet add package RuoVea.ExFilter --version 9.0.0.2
NuGet\Install-Package RuoVea.ExFilter -Version 9.0.0.2
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="RuoVea.ExFilter" Version="9.0.0.2" />
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="RuoVea.ExFilter" Version="9.0.0.2" />
<PackageReference Include="RuoVea.ExFilter" />
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add RuoVea.ExFilter --version 9.0.0.2
The NuGet Team does not provide support for this client. Please contact its maintainers for support.
#r "nuget: RuoVea.ExFilter, 9.0.0.2"
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package RuoVea.ExFilter@9.0.0.2
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=RuoVea.ExFilter&version=9.0.0.2
#tool nuget:?package=RuoVea.ExFilter&version=9.0.0.2
The NuGet Team does not provide support for this client. Please contact its maintainers for support.
📋 RuoVea.ExFilter 组件概览
RuoVea.ExFilter 是一个功能全面的 ASP.NET Core 过滤器组件,提供全局异常处理、请求日志、参数验证、API安全校验等企业级功能。
🏗️ 核心功能架构
1. 全局异常处理 (ExceptionSetup)
配置方式
// 方式一:默认配置
builder.Services.ExceptionSetup();
// 方式二:通过 Action 配置
builder.Services.ExceptionSetup(options =>
{
options.Enabled = true;
options.LogToFile = false;
options.LogMore = false;
});
// 方式三:通过配置文件
builder.Services.ExceptionSetup(builder.Configuration.GetSection("AopOption:ExceptionLog"));
配置文件
{
"ExceptionLog": {
"Enabled": true,
"LogToFile": false,
"LogMore": false
}
}
2. 请求日志拦截 (RequestActionSetup)
配置方式
// 默认配置
builder.Services.RequestActionSetup();
// 自定义配置
builder.Services.RequestActionSetup(options =>
{
options.Enabled = true;
options.LogToFile = false;
options.LogMore = false;
options.IgnoreApis = "/health,/metrics";
});
// 配置文件方式
builder.Services.RequestActionSetup(builder.Configuration.GetSection("AopOption:RequestLog"));
配置文件
{
"RequestLog": {
"Enabled": true,
"LogToFile": false,
"LogMore": false,
"IgnoreApis": "/health,/metrics"
}
}
3. 资源过滤 (ResourceSetup)
// 对资源型信息进行过滤,常用于防盗链/资源缓存
builder.Services.ResourceSetup();
4. 统一结果格式化 (ResultSetup)
// 对 API 返回结果进行统一格式化
builder.Services.ResultSetup();
5. API 安全校验 (ApISafeSetup)
配置方式
// 接口安全校验
builder.Services.ApISafeSetup(options =>
{
options.AppKeys = "key1,key2,key3";
options.AppKeyName = "appKey";
options.TimeStampName = "timeStamp";
options.ExpiresMinute = 2;
});
// 配置文件方式
builder.Services.ApISafeSetup(builder.Configuration.GetSection("AopOption:ApISafe"));
配置文件
{
"ApISafe": {
"AppKeys": "key1,key2,key3",
"AppKeyName": "appKey",
"TimeStampName": "timeStamp",
"ExpiresMinute": 2
}
}
6. 签名验证 (ApISignSetup)
配置方式
// 签名验证 MD5(appKey + signKey + timeStamp + data)
builder.Services.ApISignSetup(options =>
{
options.AppKeys = "key1,key2,key3";
options.AppKeyName = "appKey";
options.TimeStampName = "timeStamp";
options.ExpiresMinute = 2;
options.SignKey = "your-sign-key";
options.SignatureName = "signature";
options.IgnoreApi = "/public/*,/health";
});
// 配置文件方式
builder.Services.ApISignSetup(builder.Configuration.GetSection("AopOption:AppSign"));
配置文件
{
"AppSign": {
"AppKeys": "key1,key2,key3",
"AppKeyName": "appKey",
"TimeStampName": "timeStamp",
"ExpiresMinute": 2,
"SignKey": "your-sign-key",
"SignatureName": "signature",
"IgnoreApi": "/public/*,/health"
}
}
7. 前端 UI 文件处理
// 将前端 UI 压缩文件进行解压
builder.Services.AddUiFilesZipSetup();
// 使用虚拟路径中间件
app.UseVirtualPathMiddle();
虚拟路径配置
{
"VirtualPath": "/myapp"
}
🔧 核心接口和类
1. IRestfulFilterLog 接口
public interface IRestfulFilterLog
{
// 成功返回值处理
IActionResult OnSucceeded(ActionExecutedContext context, object data);
// 验证失败返回值处理
IActionResult OnValidateFailed(ActionExecutingContext context, ValidationMetadata metadata);
// 异常日志记录
void ExceptionLog(ExceptionVo exception);
// 操作日志记录
void OperationLog(OperationVo operation);
}
2. 预实现类 RestfulFilterLog
public class RestfulFilterLog : IRestfulFilterLog
{
// 操作日志记录(可重写)
public virtual void OperationLog(OperationVo operation)
{
// 默认实现
}
// 异常日志记录(可重写)
public virtual void ExceptionLog(ExceptionVo exception)
{
// 默认实现
}
}
3. 数据模型
ExceptionVo - 异常信息
public class ExceptionVo
{
public string RequestUrl { get; set; }
public string RequestMethod { get; set; }
public string UserAgent { get; set; }
public string IPAddress { get; set; }
public DateTime OccurredTime { get; set; }
public string ExceptionType { get; set; }
public string ExceptionMessage { get; set; }
public string StackTrace { get; set; }
public string InnerException { get; set; }
}
OperationVo - 操作日志
public class OperationVo
{
public string RequestUrl { get; set; }
public string RequestMethod { get; set; }
public string UserAgent { get; set; }
public string IPAddress { get; set; }
public DateTime RequestTime { get; set; }
public long ExecutionTime { get; set; }
public string Parameters { get; set; }
public string Response { get; set; }
public int StatusCode { get; set; }
public string UserId { get; set; }
public string UserName { get; set; }
}
🚀 完整使用示例
1. 自定义日志处理器
public class CustomRestfulFilterLog : RestfulFilterLog
{
private readonly ILogger<CustomRestfulFilterLog> _logger;
private readonly IOperationLogService _operationLogService;
public CustomRestfulFilterLog(ILogger<CustomRestfulFilterLog> logger,
IOperationLogService operationLogService)
{
_logger = logger;
_operationLogService = operationLogService;
}
// 重写操作日志记录方法
public override void OperationLog(OperationVo operation)
{
// 记录到日志系统
_logger.LogInformation("操作日志: {Url} {Method} {StatusCode} {ExecutionTime}ms",
operation.RequestUrl, operation.RequestMethod, operation.StatusCode, operation.ExecutionTime);
// 保存到数据库
_operationLogService.SaveAsync(new OperationLogEntity
{
Url = operation.RequestUrl,
Method = operation.RequestMethod,
UserId = operation.UserId,
UserName = operation.UserName,
IpAddress = operation.IPAddress,
UserAgent = operation.UserAgent,
Parameters = operation.Parameters,
Response = operation.Response,
StatusCode = operation.StatusCode,
ExecutionTime = operation.ExecutionTime,
RequestTime = operation.RequestTime
});
}
// 重写异常日志记录方法
public override void ExceptionLog(ExceptionVo exception)
{
// 记录异常到日志系统
_logger.LogError(exception.Exception,
"异常信息: {Url} {Method} {ExceptionType}",
exception.RequestUrl, exception.RequestMethod, exception.ExceptionType);
// 发送异常通知
SendExceptionNotification(exception);
}
private void SendExceptionNotification(ExceptionVo exception)
{
// 发送邮件、短信、钉钉等通知
// 实现异常告警逻辑
}
}
2. 自定义注册
// 注册自定义的过滤器日志处理器
builder.Services.AddRestfulSetup<CustomRestfulFilterLog>();
3. 控制器使用示例
[ApiController]
[Route("api/[controller]")]
public class UserController : ControllerBase
{
[HttpGet("profile")]
public IActionResult GetUserProfile()
{
// 自动记录操作日志和异常
var user = new { Id = 1, Name = "张三", Email = "zhangsan@example.com" };
return Ok(user);
}
[HttpPost("update")]
[NonAplSign] // 不进行签名验证
public IActionResult UpdateUser([FromBody] UserUpdateDto dto)
{
// 自动参数验证
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
// 业务逻辑...
return Ok(new { Success = true, Message = "更新成功" });
}
[HttpGet("sensitive-data")]
[NonResource] // 不对资源进行过滤
public IActionResult GetSensitiveData()
{
// 返回敏感数据,不进行资源过滤
return Ok(new { Data = "敏感信息" });
}
[HttpPost("batch-operation")]
[NonException] // 不进行异常日志收集
public IActionResult BatchOperation()
{
// 批量操作,不记录异常日志
try
{
// 业务逻辑...
return Ok();
}
catch
{
// 异常不会被全局异常过滤器捕获
return StatusCode(500);
}
}
}
4. API 安全签名验证
前端签名生成
// 前端签名生成示例
function generateSignature(appKey, signKey, data) {
const timeStamp = Math.floor(Date.now() / 1000) + 1000; // 当前时间戳+1000秒
const signContent = appKey + signKey + timeStamp + JSON.stringify(data);
return md5(signContent); // 使用 MD5 加密
}
// 请求头设置
const headers = {
'appKey': 'your-app-key',
'timeStamp': timeStamp,
'signature': generateSignature('your-app-key', 'your-sign-key', requestData)
};
后端签名验证
public class SignatureService
{
public bool VerifySignature(string appKey, string timeStamp, string data, string signature, string signKey)
{
// 验证时间戳有效期
if (!IsTimestampValid(timeStamp, 2)) // 2分钟有效期
{
return false;
}
// 验证 appKey 有效性
if (!IsAppKeyValid(appKey))
{
return false;
}
// 生成期望的签名
string expectedSignature = GenerateMD5(appKey + signKey + timeStamp + data);
// 比较签名
return signature == expectedSignature;
}
private bool IsTimestampValid(string timestamp, int expiresMinute)
{
if (!long.TryParse(timestamp, out long ts))
return false;
var requestTime = DateTimeOffset.FromUnixTimeSeconds(ts).DateTime;
var now = DateTime.Now;
return now <= requestTime && requestTime <= now.AddMinutes(expiresMinute);
}
private bool IsAppKeyValid(string appKey)
{
var validAppKeys = new[] { "key1", "key2", "key3" };
return validAppKeys.Contains(appKey);
}
private string GenerateMD5(string input)
{
using var md5 = MD5.Create();
byte[] inputBytes = Encoding.UTF8.GetBytes(input);
byte[] hashBytes = md5.ComputeHash(inputBytes);
return BitConverter.ToString(hashBytes).Replace("-", "").ToLower();
}
}
5. HTTP 上下文扩展使用
public class RequestInfoService
{
private readonly IHttpContextAccessor _httpContextAccessor;
public RequestInfoService(IHttpContextAccessor httpContextAccessor)
{
_httpContextAccessor = httpContextAccessor;
}
public RequestInfo GetRequestInfo()
{
var context = _httpContextAccessor.HttpContext;
return new RequestInfo
{
Url = context.Request.GetRequestUrlAddress(),
Host = context.Request.GetRequestHost(),
Browser = context.GetBrowser(),
OS = context.GetOSVersion(),
IP = context.GetIp(),
UserAgent = context.UserAgent(),
ClientInfo = context.GetDefault()
};
}
public void SigninToSwagger(string token)
{
_httpContextAccessor.HttpContext.SigninToSwagger(token);
}
public void SignoutFromSwagger()
{
_httpContextAccessor.HttpContext.SignoutToSwagger();
}
}
public class RequestInfo
{
public string Url { get; set; }
public string Host { get; set; }
public string Browser { get; set; }
public string OS { get; set; }
public string IP { get; set; }
public string UserAgent { get; set; }
public ClientInfo ClientInfo { get; set; }
}
6. 整合配置示例
Program.cs 完整配置
var builder = WebApplication.CreateBuilder(args);
// 添加控制器
builder.Services.AddControllers();
// 配置过滤器
builder.Services.ExceptionSetup(builder.Configuration.GetSection("AopOption:ExceptionLog"));
builder.Services.RequestActionSetup(builder.Configuration.GetSection("AopOption:RequestLog"));
builder.Services.ResourceSetup();
builder.Services.ResultSetup();
builder.Services.ApISafeSetup(builder.Configuration.GetSection("AopOption:ApISafe"));
builder.Services.ApISignSetup(builder.Configuration.GetSection("AopOption:AppSign"));
// 注册自定义过滤器日志
builder.Services.AddRestfulSetup<CustomRestfulFilterLog>();
// 规范化模型验证
builder.Services.AddRestfulModelsSetup(options =>
{
options.SuppressModelStateInvalidFilter = true;
});
// 前端 UI 文件处理
builder.Services.AddUiFilesZipSetup();
var app = builder.Build();
// 使用虚拟路径中间件
app.UseVirtualPathMiddle();
// 其他中间件...
app.UseRouting();
app.UseAuthorization();
app.MapControllers();
app.Run();
appsettings.json 完整配置
{
"AopOption": {
"RequestLog": {
"Enabled": true,
"LogToFile": false,
"LogMore": true,
"IgnoreApis": "/health,/metrics,/swagger"
},
"ExceptionLog": {
"Enabled": true,
"LogToFile": true,
"LogMore": true
},
"ApISafe": {
"AppKeys": "web-app,mobile-app,admin-app",
"AppKeyName": "appKey",
"TimeStampName": "timeStamp",
"ExpiresMinute": 2
},
"AppSign": {
"AppKeys": "web-app,mobile-app,admin-app",
"AppKeyName": "appKey",
"TimeStampName": "timeStamp",
"ExpiresMinute": 2,
"SignKey": "your-secret-sign-key-2024",
"SignatureName": "signature",
"IgnoreApi": "/public/*,/health,/swagger"
}
},
"VirtualPath": "/myapp"
}
🎯 特性排除
Non 特性列表:
[NonAplSafe]- 不进行接口安全校验[NonAplSign]- 不进行签名验证[NonException]- 不进行全局异常日志收集[NonResource]- 不对资源型信息进行过滤[NonRestfulResult]- 不对结果进行统一
🔧 设计优势
- 模块化设计:各功能可独立启用或禁用
- 灵活配置:支持代码配置和配置文件配置
- 易于扩展:接口设计支持自定义实现
- 性能优化:支持忽略特定 API
- 安全可靠:完整的 API 安全校验机制
- 多语言支持:支持简体中文、繁体中文、粤语、日语、法语、英语
这个过滤器组件为 ASP.NET Core 应用提供了企业级的全局处理能力,大幅提升了应用的稳定性、安全性和可维护性。
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net9.0 is compatible. 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. |
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
-
net9.0
- RuoVea.ExConfig (>= 9.0.0)
- RuoVea.ExCrypt (>= 9.0.0)
- RuoVea.ExDto (>= 9.0.0.3)
- RuoVea.ExLog (>= 9.0.0)
- RuoVea.ExUtil (>= 9.0.0)
- System.Security.Cryptography.Pkcs (>= 9.0.7)
- System.Security.Cryptography.Xml (>= 9.0.7)
- System.Text.RegularExpressions (>= 4.3.1)
- UAParser (>= 3.1.47)
NuGet packages (12)
Showing the top 5 NuGet packages that depend on RuoVea.ExFilter:
| Package | Downloads |
|---|---|
|
RuoVea.OmiApi.UserRoleMenu
用户、角色、菜单管理 API |
|
|
RuoVea.OmiApi.UserRole
用户角色管理 API |
|
|
RuoVea.OmiDict
字典管理 |
|
|
RuoVea.OmiConfig
参数配置 |
|
|
RuoVea.OmiApi.User
用户管理 API |
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 10.0.0.1 | 308 | 9/16/2025 |
| 9.0.0.2 | 154 | 10/23/2025 |
| 9.0.0 | 484 | 7/25/2025 |
| 8.0.1.7 | 344 | 10/23/2025 |
| 8.0.1.6 | 925 | 9/16/2025 |
| 8.0.1.5 | 1,965 | 4/23/2025 |
| 8.0.1.4 | 1,235 | 11/21/2024 |
| 8.0.1.3 | 203 | 11/1/2024 |
| 8.0.1.2 | 175 | 9/22/2024 |
| 8.0.1.1 | 194 | 9/18/2024 |
| 8.0.1 | 181 | 8/28/2024 |
| 8.0.0 | 159 | 7/23/2024 |
| 7.0.1.7 | 361 | 10/23/2025 |
| 7.0.1.6 | 1,099 | 9/16/2025 |
| 7.0.1.5 | 2,261 | 4/23/2025 |
| 7.0.1.4 | 1,426 | 11/21/2024 |
| 7.0.1.3 | 169 | 11/1/2024 |
| 7.0.1.2 | 185 | 9/22/2024 |
| 7.0.1.1 | 178 | 9/18/2024 |
| 7.0.1 | 171 | 8/28/2024 |
| 7.0.0 | 158 | 7/23/2024 |
| 6.0.19.7 | 426 | 10/23/2025 |
| 6.0.19.6 | 1,292 | 9/16/2025 |
| 6.0.19.5 | 2,729 | 4/23/2025 |
| 6.0.19.4 | 4,302 | 11/21/2024 |
| 6.0.19.3 | 1,612 | 11/1/2024 |
| 6.0.19.2 | 1,999 | 9/22/2024 |
| 6.0.19.1 | 206 | 9/18/2024 |
| 6.0.19 | 175 | 8/28/2024 |
| 6.0.18.13 | 231 | 8/25/2024 |
| 6.0.18.12 | 224 | 4/15/2024 |
| 6.0.18.11 | 215 | 4/14/2024 |
| 6.0.18.10 | 239 | 3/13/2024 |
| 6.0.18.9 | 256 | 3/13/2024 |
| 6.0.18.8 | 245 | 3/11/2024 |
| 6.0.18.7 | 300 | 2/28/2024 |
| 6.0.18.6 | 260 | 2/27/2024 |
| 6.0.18.5 | 334 | 1/29/2024 |
| 6.0.18.4 | 336 | 1/27/2024 |
| 6.0.18.3 | 302 | 1/26/2024 |
| 6.0.18.2 | 423 | 12/28/2023 |
| 6.0.18.1 | 356 | 12/1/2023 |
| 6.0.18 | 384 | 9/27/2023 |
| 6.0.17 | 370 | 9/16/2023 |
| 6.0.16 | 520 | 3/26/2023 |
| 6.0.15 | 510 | 3/26/2023 |
| 6.0.13 | 530 | 3/11/2023 |
| 6.0.12 | 583 | 12/23/2022 |
| 6.0.11 | 520 | 12/23/2022 |
| 6.0.10 | 663 | 10/8/2022 |
| 6.0.9 | 730 | 9/16/2022 |
| 6.0.8 | 706 | 8/18/2022 |
| 6.0.7 | 723 | 6/10/2022 |
| 6.0.6 | 780 | 3/15/2022 |
| 6.0.5 | 763 | 3/14/2022 |
| 6.0.4 | 747 | 2/18/2022 |
| 6.0.3 | 691 | 2/18/2022 |
| 6.0.2 | 737 | 2/17/2022 |
| 6.0.1 | 767 | 2/15/2022 |
| 6.0.0 | 774 | 2/11/2022 |
| 5.0.0.6 | 143 | 10/23/2025 |
| 5.0.0.5 | 308 | 9/16/2025 |
| 5.0.0.4 | 216 | 4/23/2025 |
| 5.0.0.3 | 183 | 11/21/2024 |
| 5.0.0.2 | 193 | 11/1/2024 |
| 5.0.0.1 | 176 | 9/22/2024 |
| 5.0.0 | 178 | 9/18/2024 |