使用 Asp.net 路由的 IRouteHandler.GetHttpHandler 中的会话为 null
我试图在 IRouteHandler 类的 GettHttpHandler 方法中启用会话,但会话始终为空。有人可以告诉我我做错了什么吗?
在 global.asax 中,我有
RouteTable.Routes.Add("All", new Route("{*page}", new MyRouteHandler()));
MyRouteHandler 类,其中 Session 为 null 如下所示:
public class MyRouteHandler : IRouteHandler, IRequiresSessionState
{
public System.Web.IHttpHandler GetHttpHandler(RequestContext requestContext)
{
string test = HttpContext.Current.Session["test"].ToString();
return BuildManager.CreateInstanceFromVirtualPath("~/Page.aspx", typeof(Page)) as Page;
}
}
我做了一个小的 测试应用程序显示问题。
有人可以告诉我我做错了什么吗?
编辑添加:
是的,我确实需要路由处理程序中的会话数据。原因有很多,但一个容易解释的原因是用户可以切换到以预览模式浏览网站。
该站点由数据库中的动态页面(/page1/page2...)层次结构组成,可以正常发布或预览。浏览网站的内容制作者可以选择仅查看普通页面或发布预览的页面。浏览模式存储在用户的会话中,因此路由处理程序需要知道浏览模式才能解决所请求的页面。
所以我真的需要在那个阶段就进行会议。
I'm trying to get Session enabled in the GettHttpHandler method of my IRouteHandler classes but session is always null. Could someone tell me what I'm doing wrong?
In global.asax I have
RouteTable.Routes.Add("All", new Route("{*page}", new MyRouteHandler()));
The MyRouteHandler class where Session is null looks like this:
public class MyRouteHandler : IRouteHandler, IRequiresSessionState
{
public System.Web.IHttpHandler GetHttpHandler(RequestContext requestContext)
{
string test = HttpContext.Current.Session["test"].ToString();
return BuildManager.CreateInstanceFromVirtualPath("~/Page.aspx", typeof(Page)) as Page;
}
}
I made a small test app that shows the problem.
Could someone tell me what I'm doing wrong?
Edited to add:
Yes, I really need session data in the route handler. There are many reasons but one easily explainable is when the user can switch to browse the site in preview mode.
The site consists of a hierarchy of dynamic pages (/page1/page2...) in the database that can be published normally or to preview. A content producer browsing the site can choose to view just normal pages or also those published to preview. The browsing mode is stored in the user's session so therefor the route handler needs to know the browsing mode to be able to solve the requested page.
So I really need the session already at that stage.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我在这个答案中解释了这个问题背后的原因。现在我已经找到了解决问题的方法!
您创建一个自定义HttpHandler类:
添加IRequiresSessionState接口非常重要,否则IIS不会为此请求加载会话。我们不需要实现
ProcessRequest
和IsReusable
的逻辑,但是类必须实现IHttpHandler接口。您更改 RouteHandler 实现:
您只需将原始的、与会话相关的逻辑移至 DelayedGetHttpHandler 函数,并在
GetHttphandler
函数中返回一个实例帮助 MyHttpHandler 类。然后,将处理逻辑挂接到
HttpApplication.PostAcquireRequestState
事件,例如在 Global.asax 中:有关更多参考,请查看此页面:https://msdn.microsoft.com/en-us/library/bb470252 (v=vs.140).aspx。它解释了请求生命周期以及我使用
PostAcquireRequestState
事件的原因。在事件处理程序中,您调用自定义 RouteHandling 函数:
就是这样。对我有用。
I have explained reason behind this problem in this answer. And now I have found a solution to the problem!
You create a custom HttpHandler class:
It is important to add IRequiresSessionState interface, otherwise IIS does not load session for this request. We do not need to implement logic of
ProcessRequest
andIsReusable
, but class must implement the IHttpHandler interface.You change your RouteHandler implementation:
You simply move your original, Session dependent logic to
DelayedGetHttpHandler
function and in theGetHttphandler
function you return an instance of the helping MyHttpHandler class.Then, you hook your handling logic to the
HttpApplication.PostAcquireRequestState
event, e.g. in the Global.asax:For more reference, check this page: https://msdn.microsoft.com/en-us/library/bb470252(v=vs.140).aspx. It explains the request lifecycle and why I use the
PostAcquireRequestState
event.In the event handler, you invoke your custom RouteHandling function:
And that's it. Works for me.
我不确定你能做到这一点(尽管我可能是错的)。我记得 IRequiresSessionState 指示 HttpHandler 需要会话状态,而不是路由处理程序(路由处理程序负责为您提供适合该路由的处理程序)。
您真的需要路由处理程序本身中的会话而不是它给出的处理程序吗?
I am not sure that you can do this (although I may be wrong). My recollection is that IRequiresSessionState indicates that an HttpHandler needs session state, rather than the route handler (which is responsible for giving you a handler appropriate to the route).
Do you really need the session in the route handler itself and not the handler it gives out?
好吧,我知道这是旧线程,但如果像我这样的人遇到同样的情况,我只是将答案放在这里,我找到了答案 此处
您所做的只是将 runAllManagedModulesForAllRequests="true" 属性添加到 web.config 中的模块标记中,如下所示
但这不是一个好的解决方案,因为它调用每次托管模块,我都使用
将其添加到 web.config 的模块部分,这是比前一个更好的解决方案。
Well I know this is old thread but just putting up the answer here if anyone like me falls in the same scenario, I found an answer here
What you do is just add a runAllManagedModulesForAllRequests="true" attribute to your modules tag in web.config like below
However this is not a good solution as it calls managed module everytime, i am using
add it in modules section of web.config, this a better solution than the previous one.