如何从 MVC5 中的自定义 RouteBase 访问 session?

How to access session from a custom RouteBase in MVC5?

我正在尝试在 ASP.NET MVC5 中实现相对透明地加密 ID 的能力。我有一系列自定义 HTML 助手,它们发出加密的 ID,例如: http://url/CityDetails/Edit/Vb7B_slYoRdt1cQD5mNum

html 助手将密钥存储在 session 范围内。

然后,我有一个实现 System.Web.Routing.RouteBase 的 class,方法 GetRouteData 应该用解密的 ID 替换加密的 ID。如果我对密钥进行硬编码,这会起作用,但如果我将密钥存储在 session 范围内,并尝试访问它,Session 始终为空。

public override RouteData GetRouteData(HttpContextBase httpContext){
     //Session is always null
     HttpSessionState session1 = System.Web.HttpContext.Current.Session;
     ...
     return routeData;
}

有办法到达 Session 吗?我显然不了解这里的生命周期。

简而言之,你不能

在 MVC 中,HttpContext.Session 在路由期间尚不可用 - 在应用程序的生命周期中还为时过早。

会话状态在 MVC 中可用的第一个点是在控制器创建阶段。

有关 MVC 生命周期的详细信息,请参阅 this MSDN article

如果将其与 ASP.NET on IIS 7 Lifecycle documentation 对齐,您可以看到路由处理程序在 PostResolveRequestCache 事件中被调用。会话状态首先在 AcquireRequestState 事件中填充,然后在 BeginProcessRequest 事件中实例化控制器并执行操作。

  1. 验证请求,检查浏览器发送的信息并确定它是否包含潜在的恶意标记。有关详细信息,请参阅 ValidateRequest 和脚本利用概述。
  2. 如果在 Web.config 文件的 UrlMappingsSection 部分中配置了任何 URL,则执行 URL 映射。
  3. 引发 BeginRequest 事件。
  4. 引发 AuthenticateRequest 事件。
  5. 引发 PostAuthenticateRequest 事件。
  6. 引发 AuthorizeRequest 事件。
  7. 引发 PostAuthorizeRequest 事件。
  8. 引发 ResolveRequestCache 事件。
  9. 引发 PostResolveRequestCache 事件。 (路由执行)
  10. 引发 MapRequestHandler 事件。根据所请求资源的文件扩展名选择适当的处理程序。处理程序可以是本机代码模块,例如 IIS 7.0 StaticFileModule 或托管代码模块,例如 PageHandlerFactory class(处理 .aspx 文件)。
  11. 引发 PostMapRequestHandler 事件。
  12. 引发 AcquireRequestState 事件。 (获得会话状态)
  13. 引发 PostAcquireRequestState 事件。
  14. 引发 PreRequestHandlerExecute 事件。
  15. 为请求调用适当的 IHttpHandler class 的 ProcessRequest 方法(或异步版本 IHttpAsyncHandler.BeginProcessRequest)。例如,如果请求是针对页面的,则当前页面实例会处理该请求。 (控制器创建)
  16. 引发 PostRequestHandlerExecute 事件。
  17. 引发 ReleaseRequestState 事件。
  18. 引发 PostReleaseRequestState 事件。
  19. 如果定义了过滤器 属性,则执行响应过滤。
  20. 引发 UpdateRequestCache 事件。
  21. 引发 PostUpdateRequestCache 事件。
  22. 引发 LogRequest 事件。
  23. 引发 PostLogRequest 事件。
  24. 引发 EndRequest 事件。
  25. 引发 PreSendRequestHeaders 事件。
  26. 引发 PreSendRequestContent 事件。

请注意它是 generally not considered a good practice to use Session state with ASP.NET MVC