Session is null in IRouteHandler.GetHttpHandler with Asp.net Routing

I am trying to enable Session in the GettHttpHandler method for my IRouteHandler classes, but the session is always zero. Can someone tell me what I am 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 application that shows the problem.

Can someone tell me what I am doing wrong?

Edited to add:

Yes, I really need session data in the route handler. There are many reasons, but it is easy to explain when the user can switch to viewing the site in preview mode.

The site consists of a hierarchy of dynamic pages (/ page1 / page2 ...) in the database, which can be published normally or for preview. The creator of the content viewing the site can choose to view only regular pages, as well as published for preview. The view mode is saved in the user session, so in order to process the requested page, the route handler must know the view mode.

Therefore, I really need a session already at this stage.

+4
source share
3 answers

I explained the cause of this problem in this answer . And now I have found a solution to the problem!

  • The custom HttpHandler class is created :

     class MyHttpHandler : IHttpHandler, IRequiresSessionState { public MyRequestHandler RequestHandler; public RequestContext Context; public MyHttpHandler(MyRequestHandler routeHandler, RequestContext context) { RouteHandler = routeHandler; Context = context; } public void ProcessRequest(HttpContext context) { throw new NotImplementedException(); } public bool IsReusable { get { throw new NotImplementedException(); } } } 

It is important to add the IRequiresSessionState interface, otherwise IIS will not load the session for this request. We do not need to implement the ProcessRequest and IsReusable , but the class must implement the IHttpHandler interface.

  1. You change the implementation of RouteHandler:

     public class MyRequestHandler : IRouteHandler { public IHttpHandler GetHttpHandler(RequestContext requestContext) { return new MyHttpHandler(this, requestContext); } public IHttpHandler DelayedGetHttpHandler(RequestContext requestContext) { // your custom routing logic comes here... } } 

You simply move the session- DelayedGetHttpHandler source logic to the DelayedGetHttpHandler function, and in the GetHttphandler function you return an instance of the MyHttpHandler help class.

  1. Then you bind the processing logic to the HttpApplication.PostAcquireRequestState event, for example. at Global.asax:

     public class Global : HttpApplication { public override void Init() { base.Init(); PostAcquireRequestState += Global_PostAcquireRequestState; } } 

For more information, check this page: https://msdn.microsoft.com/en-us/library/bb470252(v=vs.140).aspx . It explains the request life cycle and why I use the PostAcquireRequestState event.

  1. In the event handler, you call your custom RouteHandling function:

     void Global_PostAcquireRequestState(object sender, EventArgs e) { if (HttpContext.Current.Handler is MyHttpHandler) { var handler = HttpContext.Current.Handler as MyHttpHandler; HttpContext.Current.Handler = handler.RouteHandler.DelayedGetHttpHandler(handler.Context); } } 

What is it. It works for me.

+5
source

I'm not sure you can do this (although I may be wrong). My recollection is that IRequiresSessionState indicates that the HttpHandler requires a session state, not a route handler (which is responsible for providing you with a handler that matches the route).

Do you really need a session of the route handler itself, and not the handler that it issues?

+1
source

Well, I know this is an old thread, but just answering this question, if someone like me falls into the same scenario, I found the answer here

What you do is simply add the runAllManagedModulesForAllRequests = "true" attribute to the module tag in the web.config file, as shown below.

  <system.webServer> ..... <modules runAllManagedModulesForAllRequests="true"> ........ </modules> ...... </system.webServer> 

However, this is not a good solution, because every time it calls a managed module, I use

  <remove name="Session" /> <add name="Session" type="System.Web.SessionState.SessionStateModule"/> 

add it to the web.config modules section, this is a better solution than the previous one.

+1
source

Source: https://habr.com/ru/post/1313156/


All Articles