I'm getting the "SessionStateModule" object of my web aplication to append code in the start and the end of sessions. I can't put my code in Global.asax because my code intend to be a generic for every web projects.
public static void TurnOn()
{
var s = (SessionStateModule)HttpContext.Current.ApplicationInstance.Modules["Session"]
s.End += new EventHandler(s_End);
s.Start += new EventHandler(s_Start);
}
private static void s_Start(object sender, EventArgs e)
{
//foo
//bar
}
private static void s_End(object sender, EventArgs e)
{
//foo
//bar
}
The "Start" event runs perfect, but the "End" event is not firing at the end of session timeout. What is the problem?
Oh sorry -- I didn't even notice your event handlers were not in global.asax. IIRC, the 4 event handlers (App_Start, App_End, Session_Start, Session_End) are all "special" event handlers and global.asax is the only place you're allowed to have them.
I think you're getting lucky with the Session Start event, but End is a different beast. Think about it -- Start can be associated with a HTTP request (which is where the module is involved). But End is just some background thread noticing the user hasn't
been back in a while -- there's no request that triggers that.
I recall looking at the ASP.NET source code a long time ago and recalling that those 4 special methods are specially configured by ASP.NET runtime and I've never seen anything that suggests that what you're doing is supported other than in global.asax. Doesn't
mean it can't be hacked (like your session start code). :)
the 4 event handlers (App_Start, App_End, Session_Start, Session_End) are all "special" event handlers
Yes, I understandthat these 4
eventsare special,mainly becausethey
are runby beingwith yourspecial name(possibly byReflection).
BrockAllen
Think about it -- Start can be associated with a HTTP request (which is where the module is involved). But End is just some background thread noticing the user hasn't been back in a while -- there's no request that triggers that.
The same way
that somethingis capable of firing
the traditional methodsSession_StartandSession_End,thissame mechanism
is firingmy eventStartadded,but
for some reasonis not firingtheEnd.
Please, i would likea solution to bypass
this problem, i've heardthat it is possibleto create my ownsession controlmodule implementing the IHttpModule interfaceto replace the defaultSessionStateModule, butI think itwill require
a lot of codeto implement.
Another option is inherit theHttpApplication class of the Global.asax implementingSession_Start
andSession_End intheirtraditional way,but that is bad for my goalof leaving thegeneric code
for various projects.
Yea, I think you're out of luck (without reflection). I just looked at the code in reflector (HttpApplicationFactory.ReflectOnApplicationType and HttpApplicationFactory.ReflectOnMethodInfoIfItLooksLikeEventHandler) and they're using reflection to look for
Session_Start on the HttpApp-derived class (the one in global.asax). You'd have to assign a MethodInfo on the private member HttpApplicationFactory_sessionOnEndMethod to overwrite/replace the existing event in global.asax.
I tried your solution and it doesn't work for me since I don't know what is the "not_relevant" variable in your code. Please coul'd you help me since I'm not able to get the End event working in my httpmodule even if the mode is set to InProc...
thanks
chogoki
0 Points
5 Posts
SessionStateModule "End" event not firing
Aug 24, 2012 08:22 PM|LINK
Hi,
I'm getting the "SessionStateModule" object of my web aplication to append code in the start and the end of sessions. I can't put my code in Global.asax because my code intend to be a generic for every web projects.
public static void TurnOn() { var s = (SessionStateModule)HttpContext.Current.ApplicationInstance.Modules["Session"] s.End += new EventHandler(s_End); s.Start += new EventHandler(s_Start); } private static void s_Start(object sender, EventArgs e) { //foo //bar } private static void s_End(object sender, EventArgs e) { //foo //bar }The "Start" event runs perfect, but the "End" event is not firing at the end of session timeout. What is the problem?
BrockAllen
All-Star
27574 Points
4912 Posts
MVP
Re: SessionStateModule "End" event not firing
Aug 24, 2012 09:47 PM|LINK
If Session is maintained out of proc, then the Session End event is not fired in ASP.NET.
DevelopMentor | http://www.develop.com
thinktecture | http://www.thinktecture.com/
chogoki
0 Points
5 Posts
Re: SessionStateModule "End" event not firing
Aug 24, 2012 10:16 PM|LINK
The Start event is running normally and i'm using the InProc mode in Web.config.
BrockAllen
All-Star
27574 Points
4912 Posts
MVP
Re: SessionStateModule "End" event not firing
Aug 24, 2012 11:17 PM|LINK
Oh sorry -- I didn't even notice your event handlers were not in global.asax. IIRC, the 4 event handlers (App_Start, App_End, Session_Start, Session_End) are all "special" event handlers and global.asax is the only place you're allowed to have them.
I think you're getting lucky with the Session Start event, but End is a different beast. Think about it -- Start can be associated with a HTTP request (which is where the module is involved). But End is just some background thread noticing the user hasn't been back in a while -- there's no request that triggers that.
I recall looking at the ASP.NET source code a long time ago and recalling that those 4 special methods are specially configured by ASP.NET runtime and I've never seen anything that suggests that what you're doing is supported other than in global.asax. Doesn't mean it can't be hacked (like your session start code). :)
DevelopMentor | http://www.develop.com
thinktecture | http://www.thinktecture.com/
chogoki
0 Points
5 Posts
Re: SessionStateModule "End" event not firing
Aug 25, 2012 01:05 AM|LINK
Yes, I understand that these 4 events are special, mainly because they are run by being with your special name (possibly by Reflection).
The same way that something is capable of firing the traditional methods Session_Start and Session_End, this same mechanism is firing my event Start added, but for some reason is not firing the End.
Please, i would like a solution to bypass this problem, i've heard that it is possible to create my own session control module implementing the IHttpModule interface to replace the default SessionStateModule, but I think it will require a lot of code to implement. Another option is inherit the HttpApplication class of the Global.asax implementing Session_Start and Session_End in their traditional way, but that is bad for my goal of leaving the generic code for various projects.
Any suggestions?
BrockAllen
All-Star
27574 Points
4912 Posts
MVP
Re: SessionStateModule "End" event not firing
Aug 25, 2012 04:12 AM|LINK
Yea, I think you're out of luck (without reflection). I just looked at the code in reflector (HttpApplicationFactory.ReflectOnApplicationType and HttpApplicationFactory.ReflectOnMethodInfoIfItLooksLikeEventHandler) and they're using reflection to look for Session_Start on the HttpApp-derived class (the one in global.asax). You'd have to assign a MethodInfo on the private member HttpApplicationFactory_sessionOnEndMethod to overwrite/replace the existing event in global.asax.
DevelopMentor | http://www.develop.com
thinktecture | http://www.thinktecture.com/
chogoki
0 Points
5 Posts
Re: SessionStateModule "End" event not firing
Aug 27, 2012 12:00 PM|LINK
Then the luck came to me now. ;)
public static void TurnOn() { //Session Start var s = (SessionStateModule)HttpContext.Current.ApplicationInstance.Modules["Session"] s.Start += new EventHandler(s_Start); //Session End var webAssembly = Assembly.GetAssembly(typeof(HttpApplication)); var t = webAssembly.GetType("System.Web.HttpApplicationFactory", true); var fieldtheApplicationFactory = t.GetField("_theApplicationFactory", BindingFlags.NonPublic | BindingFlags.Static); var fieldEnd = t.GetField("_sessionOnEndMethod", BindingFlags.NonPublic | BindingFlags.Instance); var appFactory = fieldtheApplicationFactory.GetValue(null); lock (appFactory) { fieldEnd.SetValue(appFactory, typeof(not_relevant).GetMethod("s_End", BindingFlags.NonPublic | BindingFlags.Static)); } } private static void s_Start(object sender, EventArgs e) { //foo //bar } private static void s_End(object sender, EventArgs e) { //To-do: Preserve the original Session_End from Global.asax //foo //bar }Thanks for helping.
jeanfre777
Member
2 Points
2 Posts
Re: SessionStateModule "End" event not firing
Jan 17, 2013 03:30 PM|LINK
chogoki
0 Points
5 Posts
Re: SessionStateModule "End" event not firing
Jan 18, 2013 05:12 PM|LINK
The not_relevant type is the static class name where you put the s_End method.