Razor Pages项目中如何在Startup.cs的Middleware里访问TempData?
Razor Pages 中间件访问TempData问题解答
你的实现思路属于不良实践,原因如下
- TempData是专为Razor Pages、MVC控制器等上层应用层设计的组件,核心定位是跨请求传递页面/控制器层面的临时数据,不属于中间件层的依赖范畴,耦合后会破坏请求管道的职责分离原则,大幅降低中间件的通用性。
- 默认TempData基于Session实现,且其初始化依赖MVC/Razor Pages相关中间件的执行,如果你的自定义中间件注册位置在MVC相关中间件之前,TempData实例还未完成初始化,自然无法访问。
- 中间件属于请求管道的通用底层组件,依赖上层业务层的API会导致代码架构混乱,后续维护成本极高。
中间件读取运行时生成值的正确方案
你可以根据使用场景选择以下适配方案:
方案1:使用HttpContext.Items传递单个请求内的临时值
如果你的值只需要在当前单个请求的各个管道组件间传递,不需要跨请求,这是最优选择:
- 无需额外注册服务,你可以在请求处理的任意阶段通过
context.Items["自定义键名"] = 存储值写入,在其他中间件、页面处理逻辑中直接读取即可。该存储的生命周期仅为当前请求,请求结束后会自动释放。
方案2:使用Session存储跨请求的临时值
如果你的值需要跨多个请求传递,和TempData的默认能力匹配,直接访问Session即可:
- 先在
Startup.ConfigureServices中注册Session服务:
services.AddSession(options => { // 按需配置过期时间等参数 options.IdleTimeout = TimeSpan.FromMinutes(20); options.Cookie.HttpOnly = true; options.Cookie.IsEssential = true; });
- 在
Startup.Configure方法中,将app.UseSession()注册到你的自定义中间件之前:
app.UseSession(); // 你的自定义中间件要注册在UseSession之后 app.UseMiddleware<你的自定义中间件类>(); app.UseRouting(); // 其余中间件逻辑
- 在中间件中直接读写Session:
// 写入 context.Session.SetString("自定义键名", "要存储的值"); // 读取 var targetValue = context.Session.GetString("自定义键名");
方案3:读取后续管道逻辑生成的值
如果你需要读取的是自定义中间件后面的管道(比如Razor Pages处理逻辑)生成的值,将读取逻辑放在await next()之后执行即可,先执行后续的管道逻辑,等值生成后再回到你的中间件做处理:
public async Task InvokeAsync(HttpContext context, RequestDelegate next) { // 这里是请求刚进入中间件的逻辑,后续管道未执行,拿不到后面生成的值 await next(context); // 这里是后续管道执行完成后的逻辑,可正常读取后续逻辑写入Items、Session中的值 }
补充说明:如果确实有特殊场景必须在中间件中访问TempData,可通过依赖注入获取
ITempDataDictionaryFactory创建实例,但该方案违背架构设计原则,非常不推荐使用:var tempDataFactory = context.RequestServices.GetRequiredService<ITempDataDictionaryFactory>(); var tempData = tempDataFactory.GetTempData(context); // 读取TempData中的值 var targetValue = tempData["自定义键名"];
内容的提问来源于stack exchange,提问作者StaPantazis
相关产品推荐
相关产品推荐

