.net core 过滤器中给控制器传递参数。.net6,.net 9过滤器控制器传参 电脑版发表于:2025/3/17 22:35 tn2>需求:在.net9的web 项目里边创建了一个过滤器,过滤器里边就是验证token,然后取出来token里边的数据,得到了一个CurrentUser对象,现在我想在控制器里边去获取这个对象,可以把过滤器里边创建的对象传递到控制器里边,比如我控制器里边有一个这样的属性:public CurrentUser currentUser { get; },需要把过滤器里边创建好的这个对象赋值给控制器里边的这个对象呢。 在 ASP.NET Core 中,将过滤器中解析的 `CurrentUser` 对象传递到控制器,可以通过以下两种主流方案实现: [TOC] --- ### **方案 1:通过 `HttpContext.Items` 传递(推荐)** 利用 HTTP 请求上下文的 `Items` 集合临时存储数据,这是 ASP.NET Core 中跨组件传递请求级数据的标准做法。 #### **实现步骤:** 1. **在过滤器中存储对象**: ```csharp public class JwtAuthorizationFilter : IAuthorizationFilter { public void OnAuthorization(AuthorizationFilterContext context) { // 解析 Token 并创建 CurrentUser 对象 var loginUserInfo = ParseToken(context.HttpContext.Request.Headers["Authorization"]); // 将对象存入 HttpContext.Items context.HttpContext.Items["CurrentUser"] = loginUserInfo; } } ``` 2. **在控制器中通过属性获取**: ```csharp public class MyController : ControllerBase { private CurrentUser _currentUser; public CurrentUser currentUser => _currentUser ??= HttpContext.Items["CurrentUser"] as CurrentUser; // 或者通过构造函数直接注入 IHttpContextAccessor private readonly IHttpContextAccessor _httpContextAccessor; public MyController(IHttpContextAccessor httpContextAccessor) { _httpContextAccessor = httpContextAccessor; } public IActionResult Get() { var user = _httpContextAccessor.HttpContext?.Items["CurrentUser"] as CurrentUser; // 使用 user... } } ``` **优点**: - 无需修改依赖注入容器,简单直接。 - 天然支持请求作用域,数据自动隔离。 **缺点**: - 需要手动从 `HttpContext.Items` 中提取数据。 --- ### **方案 2:通过依赖注入(Scoped 服务)** 将 `CurrentUser` 注册为 **Scoped 生命周期服务**,在过滤器中动态替换实现。 #### **实现步骤:** 1. **定义接口和默认实现**: ```csharp public interface ICurrentUserAccessor { CurrentUser CurrentUser { get; } } public class CurrentUserAccessor : ICurrentUserAccessor { public CurrentUser CurrentUser { get; private set; } } ``` 2. **在 `Program.cs` 中注册服务**: ```csharp builder.Services.AddScoped<ICurrentUserAccessor, CurrentUserAccessor>(); ``` 3. **在过滤器中替换服务实现**: ```csharp public class JwtAuthorizationFilter : IAuthorizationFilter { public void OnAuthorization(AuthorizationFilterContext context) { var loginUserInfo = ParseToken(context.HttpContext.Request.Headers["Authorization"]); // 获取当前作用域的服务提供程序 var scopedServiceProvider = context.HttpContext.RequestServices.CreateScope().ServiceProvider; var currentUserAccessor = scopedServiceProvider.GetRequiredService<ICurrentUserAccessor>(); currentUserAccessor.CurrentUser = loginUserInfo; } } ``` 4. **在控制器中通过构造函数注入**: ```csharp public class MyController : ControllerBase { private readonly ICurrentUserAccessor _currentUserAccessor; public CurrentUser currentUser => _currentUserAccessor.CurrentUser; public MyController(ICurrentUserAccessor currentUserAccessor) { _currentUserAccessor = currentUserAccessor; } } ``` **优点**: - 符合依赖注入原则,控制器代码更简洁。 - 便于单元测试(可模拟 `ICurrentUserAccessor`)。 **缺点**: - 需要额外定义接口和实现类。 - 需确保过滤器在作用域内正确替换服务。 --- ### **选择建议** - **简单场景**:优先使用 `HttpContext.Items`,无需额外配置。 - **复杂逻辑或需强类型访问**:选择依赖注入方案,代码更规范。 两种方案均能安全传递请求级数据,根据你的项目复杂度选择即可。****