ASP.NET Core 中过滤器与控制器间的数据交互机制
在 ASP.NET Core 应用中,实现过滤器与控制器之间的数据传递是常见需求。通过合理选择方法,可以在请求处理流程中高效地共享信息。以下是几种典型且实用的实现方式:
1. 利用 HttpContext.Items 实现临时数据存储
HttpContext.Items 提供了一个轻量级的字典结构,用于在单个请求生命周期内保存临时数据,适用于跨组件共享上下文信息。
public class LoggingFilter : IActionFilter
{
public void OnActionExecuting(ActionExecutingContext context)
{
context.HttpContext.Items["StartTime"] = DateTime.UtcNow;
}
public void OnActionExecuted(ActionExecutedContext context)
{
var startTime = context.HttpContext.Items["StartTime"] as DateTime?;
if (startTime.HasValue)
{
var duration = DateTime.UtcNow - startTime.Value;
// 记录执行耗时
}
}
}
public class ProductController : Controller
{
public IActionResult Details(int id)
{
var startTime = HttpContext.Items["StartTime"] as DateTime?;
return View(new { Id = id, StartTime = startTime });
}
}
2. 通过 RouteData 传递路由相关参数
RouteData.Values 是路由系统的一部分,可用于在过滤器中动态注入或修改路由值,从而影响控制器逻辑。
public class AuthCheckFilter : IActionFilter
{
public void OnActionExecuting(ActionExecutingContext context)
{
var role = context.RouteData.Values["role"] as string;
if (string.IsNullOrEmpty(role))
{
context.RouteData.Values["role"] = "guest";
}
}
public void OnActionExecuted(ActionExecutedContext context) { }
}
public class AdminController : Controller
{
public IActionResult Dashboard()
{
var userRole = RouteData.Values["role"] as string;
return View(new { UserRole = userRole });
}
}
3. 修改 ActionArguments 实现参数注入
若需在执行前动态更改控制器方法的输入参数,可直接操作 ActionExecutingContext.ActionArguments 集合。
public class DefaultParamFilter : IActionFilter
{
public void OnActionExecuting(ActionExecutingContext context)
{
if (context.ActionArguments.TryGetValue("searchTerm", out var value) && value == null)
{
context.ActionArguments["searchTerm"] = "default";
}
}
public void OnActionExecuted(ActionExecutedContext context) { }
}
public IActionResult Search(string searchTerm)
{
return View(new { Query = searchTerm });
}
4. 借助依赖注入实现共享状态管理
对于需要持久化或复杂状态共享的场景,推荐使用依赖注入注册一个共享服务,确保多个组件访问同一实例。
public interface IRequestContextService
{
string CurrentUser { get; set; }
Dictionary Metadata { get; }
}
public class RequestContextServiceImpl : IRequestContextService
{
public string CurrentUser { get; set; } = "anonymous";
public Dictionary Metadata { get; } = new();
}
// Startup.cs 配置
services.AddSingleton();
public class AuditFilter : IActionFilter
{
private readonly IRequestContextService _context;
public AuditFilter(IRequestContextService context)
{
_context = context;
}
public void OnActionExecuting(ActionExecutingContext context)
{
_context.CurrentUser = "admin";
_context.Metadata["RequestTimestamp"] = DateTime.UtcNow;
}
public void OnActionExecuted(ActionExecutedContext context) { }
}
public class OrderController : Controller
{
private readonly IRequestContextService _context;
public OrderController(IRequestContextService context)
{
_context = context;
}
public IActionResult Create()
{
return View(new
{
User = _context.CurrentUser,
Timestamp = _context.Metadata["RequestTimestamp"]
});
}
}
以上方法各有适用场景:Items 适合短期上下文;RouteData 用于路由关联;ActionArguments 支持参数重写;而依赖注入服务则更适合长期状态管理和复杂业务逻辑共享。